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_newerXY
, "newerXY "},
204 {pred_nogroup
, "nogroup "},
205 {pred_nouser
, "nouser "},
207 {pred_okdir
, "okdir "},
210 {pred_path
, "path "},
211 {pred_perm
, "perm "},
212 {pred_print
, "print "},
213 {pred_print0
, "print0 "},
214 {pred_prune
, "prune "},
215 {pred_quit
, "quit "},
216 {pred_readable
, "readable "},
217 {pred_regex
, "regex "},
218 {pred_samefile
,"samefile "},
219 {pred_size
, "size "},
220 {pred_true
, "true "},
221 {pred_type
, "type "},
223 {pred_used
, "used "},
224 {pred_user
, "user "},
225 {pred_writable
, "writable "},
226 {pred_xtype
, "xtype "},
231 /* Returns ts1 - ts2 */
232 static double ts_difference(struct timespec ts1
,
235 double d
= difftime(ts1
.tv_sec
, ts2
.tv_sec
)
236 + (1.0e-9 * (ts1
.tv_nsec
- ts2
.tv_nsec
));
242 compare_ts(struct timespec ts1
,
245 if ((ts1
.tv_sec
== ts2
.tv_sec
) &&
246 (ts1
.tv_nsec
== ts2
.tv_nsec
))
252 double diff
= ts_difference(ts1
, ts2
);
253 return diff
< 0.0 ? -1 : +1;
257 /* Predicate processing routines.
259 PATHNAME is the full pathname of the file being checked.
260 *STAT_BUF contains information about PATHNAME.
261 *PRED_PTR contains information for applying the predicate.
263 Return true if the file passes this predicate, false if not. */
268 * Returns true if THE_TIME is
269 * COMP_GT: after the specified time
270 * COMP_LT: before the specified time
271 * COMP_EQ: less than WINDOW seconds after the specified time.
274 pred_timewindow(struct timespec ts
, struct predicate
const *pred_ptr
, int window
)
278 switch (pred_ptr
->args
.reftime
.kind
)
281 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) > 0;
284 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) < 0;
287 delta
= ts_difference(ts
, pred_ptr
->args
.reftime
.ts
);
288 return (delta
>= 0.0 && delta
< window
);
294 pred_amin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
297 return pred_timewindow(get_stat_atime(stat_buf
), pred_ptr
, 60);
301 pred_and (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
303 if (pred_ptr
->pred_left
== NULL
304 || (*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
305 pred_ptr
->pred_left
))
307 /* Check whether we need a stat here. */
308 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
310 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
311 pred_ptr
->pred_right
));
318 pred_anewer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
321 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
322 return compare_ts(get_stat_atime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
326 pred_atime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
329 return pred_timewindow(get_stat_atime(stat_buf
), 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(get_stat_ctime(stat_buf
), pred_ptr
, 60);
350 pred_cnewer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
354 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
355 return compare_ts(get_stat_ctime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
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(get_stat_ctime(stat_buf
), 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
);
457 /* Push the argument onto the current list.
458 * The command may or may not be run at this point,
459 * depending on the command line length limits.
461 bc_push_arg(&execp
->ctl
,
467 /* POSIX: If the primary expression is punctuated by a plus
468 * sign, the primary shall always evaluate as true
476 for (i
=0; i
<execp
->num_args
; ++i
)
478 bc_do_insert(&execp
->ctl
,
480 execp
->replace_vec
[i
],
481 strlen(execp
->replace_vec
[i
]),
487 /* Actually invoke the command. */
488 return execp
->ctl
.exec_callback(&execp
->ctl
,
495 pred_exec (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
497 return new_impl_pred_exec(pathname
, stat_buf
, pred_ptr
, NULL
, 0);
501 pred_execdir (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
503 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
505 return new_impl_pred_exec (state
.rel_pathname
, stat_buf
, pred_ptr
,
506 prefix
, (prefix
? 2 : 0));
510 pred_false (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
521 pred_fls (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
523 list_file (pathname
, state
.rel_pathname
, stat_buf
, options
.start_time
.tv_sec
,
524 options
.output_block_size
,
525 pred_ptr
->literal_control_chars
, pred_ptr
->args
.stream
);
530 pred_fprint (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
535 print_quoted(pred_ptr
->args
.printf_vec
.stream
,
536 pred_ptr
->args
.printf_vec
.quote_opts
,
537 pred_ptr
->args
.printf_vec
.dest_is_tty
,
544 pred_fprint0 (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
549 fputs (pathname
, pred_ptr
->args
.stream
);
550 putc (0, pred_ptr
->args
.stream
);
557 mode_to_filetype(mode_t m
)
560 m
== S_IFSOCK
? "s" :
567 m
== S_IFDOOR
? "D" :
569 m
== S_IFIFO
? "p" : "U";
573 file_sparseness(const struct stat
*p
)
577 if (0 == p
->st_blocks
)
580 return p
->st_blocks
< 0 ? -HUGE_VAL
: HUGE_VAL
;
584 double blklen
= file_blocksize(p
) * (double)p
->st_blocks
;
585 return blklen
/ p
->st_size
;
593 struct segment
*segment
,
595 const struct stat
*stat_buf
,
597 const struct quoting_options
*qopts
)
599 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
602 switch (segment
->segkind
)
604 case KIND_PLAIN
: /* Plain text string (no % conversion). */
606 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
609 case KIND_STOP
: /* Terminate argument and flush output. */
611 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
616 switch (segment
->format_char
[0])
618 case 'a': /* atime in `ctime' format. */
619 /* UNTRUSTED, probably unexploitable */
620 fprintf (fp
, segment
->text
, ctime_format (get_stat_atime(stat_buf
)));
622 case 'b': /* size in 512-byte blocks */
623 /* UNTRUSTED, probably unexploitable */
624 fprintf (fp
, segment
->text
,
625 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
627 ST_NBLOCKSIZE
, 512));
629 case 'c': /* ctime in `ctime' format */
630 /* UNTRUSTED, probably unexploitable */
631 fprintf (fp
, segment
->text
, ctime_format (get_stat_ctime(stat_buf
)));
633 case 'd': /* depth in search tree */
634 /* UNTRUSTED, probably unexploitable */
635 fprintf (fp
, segment
->text
, state
.curdepth
);
637 case 'D': /* Device on which file exists (stat.st_dev) */
639 fprintf (fp
, segment
->text
,
640 human_readable ((uintmax_t) stat_buf
->st_dev
, hbuf
,
641 human_ceiling
, 1, 1));
643 case 'f': /* base name of path */
645 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, base_name (pathname
));
647 case 'F': /* filesystem type */
649 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, filesystem_type (stat_buf
, pathname
));
651 case 'g': /* group name */
653 /* (well, the actual group is selected by the user but
654 * its name was selected by the system administrator)
659 g
= getgrgid (stat_buf
->st_gid
);
662 segment
->text
[segment
->text_len
] = 's';
663 fprintf (fp
, segment
->text
, g
->gr_name
);
672 case 'G': /* GID number */
673 /* UNTRUSTED, probably unexploitable */
674 fprintf (fp
, segment
->text
,
675 human_readable ((uintmax_t) stat_buf
->st_gid
, hbuf
,
676 human_ceiling
, 1, 1));
678 case 'h': /* leading directories part of path */
683 cp
= strrchr (pathname
, '/');
684 if (cp
== NULL
) /* No leading directories. */
686 /* If there is no slash in the pathname, we still
687 * print the string because it contains characters
688 * other than just '%s'. The %h expands to ".".
690 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, ".");
696 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, pathname
);
701 case 'H': /* ARGV element file was found under */
704 char cc
= pathname
[state
.starting_path_length
];
706 pathname
[state
.starting_path_length
] = '\0';
707 fprintf (fp
, segment
->text
, pathname
);
708 pathname
[state
.starting_path_length
] = cc
;
711 case 'i': /* inode number */
712 /* UNTRUSTED, but not exploitable I think */
713 fprintf (fp
, segment
->text
,
714 human_readable ((uintmax_t) stat_buf
->st_ino
, hbuf
,
718 case 'k': /* size in 1K blocks */
719 /* UNTRUSTED, but not exploitable I think */
720 fprintf (fp
, segment
->text
,
721 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
723 ST_NBLOCKSIZE
, 1024));
725 case 'l': /* object of symlink */
731 if (S_ISLNK (stat_buf
->st_mode
))
733 linkname
= get_link_name (pathname
, state
.rel_pathname
);
735 state
.exit_status
= 1;
739 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, linkname
);
743 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, "");
748 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
749 /* UNTRUSTED, probably unexploitable */
751 char modestring
[16] ;
752 filemodestring (stat_buf
, modestring
);
753 modestring
[10] = '\0';
754 fprintf (fp
, segment
->text
, modestring
);
758 case 'm': /* mode as octal number (perms only) */
759 /* UNTRUSTED, probably unexploitable */
761 /* Output the mode portably using the traditional numbers,
762 even if the host unwisely uses some other numbering
763 scheme. But help the compiler in the common case where
764 the host uses the traditional numbering scheme. */
765 mode_t m
= stat_buf
->st_mode
;
766 boolean traditional_numbering_scheme
=
767 (S_ISUID
== 04000 && S_ISGID
== 02000 && S_ISVTX
== 01000
768 && S_IRUSR
== 00400 && S_IWUSR
== 00200 && S_IXUSR
== 00100
769 && S_IRGRP
== 00040 && S_IWGRP
== 00020 && S_IXGRP
== 00010
770 && S_IROTH
== 00004 && S_IWOTH
== 00002 && S_IXOTH
== 00001);
771 fprintf (fp
, segment
->text
,
772 (traditional_numbering_scheme
774 : ((m
& S_ISUID
? 04000 : 0)
775 | (m
& S_ISGID
? 02000 : 0)
776 | (m
& S_ISVTX
? 01000 : 0)
777 | (m
& S_IRUSR
? 00400 : 0)
778 | (m
& S_IWUSR
? 00200 : 0)
779 | (m
& S_IXUSR
? 00100 : 0)
780 | (m
& S_IRGRP
? 00040 : 0)
781 | (m
& S_IWGRP
? 00020 : 0)
782 | (m
& S_IXGRP
? 00010 : 0)
783 | (m
& S_IROTH
? 00004 : 0)
784 | (m
& S_IWOTH
? 00002 : 0)
785 | (m
& S_IXOTH
? 00001 : 0))));
789 case 'n': /* number of links */
790 /* UNTRUSTED, probably unexploitable */
791 fprintf (fp
, segment
->text
,
792 human_readable ((uintmax_t) stat_buf
->st_nlink
,
797 case 'p': /* pathname */
799 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, pathname
);
801 case 'P': /* pathname with ARGV element stripped */
803 if (state
.curdepth
> 0)
805 cp
= pathname
+ state
.starting_path_length
;
807 /* Move past the slash between the ARGV element
808 and the rest of the pathname. But if the ARGV element
809 ends in a slash, we didn't add another, so we've
810 already skipped past it. */
815 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, cp
);
817 case 's': /* size in bytes */
818 /* UNTRUSTED, probably unexploitable */
819 fprintf (fp
, segment
->text
,
820 human_readable ((uintmax_t) stat_buf
->st_size
,
821 hbuf
, human_ceiling
, 1, 1));
824 case 'S': /* sparseness */
825 /* UNTRUSTED, probably unexploitable */
826 fprintf (fp
, segment
->text
, file_sparseness(stat_buf
));;
829 case 't': /* mtime in `ctime' format */
830 /* UNTRUSTED, probably unexploitable */
831 fprintf (fp
, segment
->text
, ctime_format (get_stat_mtime(stat_buf
)));
834 case 'u': /* user name */
836 /* (well, the actual user is selected by the user on systems
837 * where chown is not restricted, but the user name was
838 * selected by the system administrator)
843 p
= getpwuid (stat_buf
->st_uid
);
846 segment
->text
[segment
->text_len
] = 's';
847 fprintf (fp
, segment
->text
, p
->pw_name
);
853 case 'U': /* UID number */
854 /* UNTRUSTED, probably unexploitable */
855 fprintf (fp
, segment
->text
,
856 human_readable ((uintmax_t) stat_buf
->st_uid
, hbuf
,
857 human_ceiling
, 1, 1));
860 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */
861 case 'Y': /* in case of symlink */
865 if (S_ISLNK (stat_buf
->st_mode
))
868 /* If we would normally follow links, do not do so.
869 * If we would normally not follow links, do so.
871 if ((following_links() ? lstat
: stat
)
872 (state
.rel_pathname
, &sbuf
) != 0)
874 if ( errno
== ENOENT
) {
875 fprintf (fp
, segment
->text
, "N");
878 if ( errno
== ELOOP
) {
879 fprintf (fp
, segment
->text
, "L");
882 error (0, errno
, "%s", pathname
);
886 fprintf (fp
, segment
->text
,
887 mode_to_filetype(sbuf
.st_mode
& S_IFMT
));
892 fprintf (fp
, segment
->text
,
893 mode_to_filetype(stat_buf
->st_mode
& S_IFMT
));
901 fprintf (fp
, segment
->text
,
902 mode_to_filetype(stat_buf
->st_mode
& S_IFMT
));
908 #warning this function needs a return statement. See Savannah bug#19146.
912 pred_fprintf (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
914 FILE *fp
= pred_ptr
->args
.printf_vec
.stream
;
915 struct segment
*segment
;
916 boolean ttyflag
= pred_ptr
->args
.printf_vec
.dest_is_tty
;
917 const struct quoting_options
*qopts
= pred_ptr
->args
.printf_vec
.quote_opts
;
919 for (segment
= pred_ptr
->args
.printf_vec
.segment
; segment
;
920 segment
= segment
->next
)
922 if ( (KIND_FORMAT
== segment
->segkind
) && segment
->format_char
[1]) /* Component of date. */
926 switch (segment
->format_char
[0])
929 ts
= get_stat_atime(stat_buf
);
932 ts
= get_stat_ctime(stat_buf
);
935 ts
= get_stat_mtime(stat_buf
);
941 /* We trust the output of format_date not to contain
942 * nasty characters, though the value of the date
943 * is itself untrusted data.
946 fprintf (fp
, segment
->text
,
947 format_date (ts
, segment
->format_char
[1]));
951 do_fprintf(fp
, segment
, pathname
, stat_buf
, ttyflag
, qopts
);
958 pred_fstype (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
962 if (strcmp (filesystem_type (stat_buf
, pathname
), pred_ptr
->args
.str
) == 0)
969 pred_gid (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
973 switch (pred_ptr
->args
.numinfo
.kind
)
976 if (stat_buf
->st_gid
> pred_ptr
->args
.numinfo
.l_val
)
980 if (stat_buf
->st_gid
< pred_ptr
->args
.numinfo
.l_val
)
984 if (stat_buf
->st_gid
== pred_ptr
->args
.numinfo
.l_val
)
992 pred_group (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
996 if (pred_ptr
->args
.gid
== stat_buf
->st_gid
)
1003 pred_ilname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1005 return match_lname (pathname
, stat_buf
, pred_ptr
, true);
1009 pred_iname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1015 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1016 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1018 base
= base_name (pathname
);
1019 if (fnmatch (pred_ptr
->args
.str
, base
, FNM_CASEFOLD
) == 0)
1025 pred_inum (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1029 switch (pred_ptr
->args
.numinfo
.kind
)
1032 if (stat_buf
->st_ino
> pred_ptr
->args
.numinfo
.l_val
)
1036 if (stat_buf
->st_ino
< pred_ptr
->args
.numinfo
.l_val
)
1040 if (stat_buf
->st_ino
== pred_ptr
->args
.numinfo
.l_val
)
1048 pred_ipath (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1052 if (fnmatch (pred_ptr
->args
.str
, pathname
, FNM_CASEFOLD
) == 0)
1058 pred_links (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1062 switch (pred_ptr
->args
.numinfo
.kind
)
1065 if (stat_buf
->st_nlink
> pred_ptr
->args
.numinfo
.l_val
)
1069 if (stat_buf
->st_nlink
< pred_ptr
->args
.numinfo
.l_val
)
1073 if (stat_buf
->st_nlink
== pred_ptr
->args
.numinfo
.l_val
)
1081 pred_lname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1083 return match_lname (pathname
, stat_buf
, pred_ptr
, false);
1087 match_lname (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
)
1089 boolean ret
= false;
1091 if (S_ISLNK (stat_buf
->st_mode
))
1093 char *linkname
= get_link_name (pathname
, state
.rel_pathname
);
1096 if (fnmatch (pred_ptr
->args
.str
, linkname
,
1097 ignore_case
? FNM_CASEFOLD
: 0) == 0)
1102 #endif /* S_ISLNK */
1107 pred_ls (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1109 list_file (pathname
, state
.rel_pathname
, stat_buf
, options
.start_time
.tv_sec
,
1110 options
.output_block_size
,
1111 pred_ptr
->literal_control_chars
,
1117 pred_mmin (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1120 return pred_timewindow(get_stat_mtime(stat_buf
), pred_ptr
, 60);
1124 pred_mtime (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1127 return pred_timewindow(get_stat_mtime(stat_buf
), pred_ptr
, DAYSECS
);
1131 pred_name (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1136 base
= base_name (pathname
);
1138 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1139 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1141 if (fnmatch (pred_ptr
->args
.str
, base
, 0) == 0)
1147 pred_negate (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1149 /* Check whether we need a stat here. */
1150 /* TODO: what about need_type? */
1151 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
1153 return (!(*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
1154 pred_ptr
->pred_right
));
1158 pred_newer (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1162 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
1163 return compare_ts(get_stat_mtime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
1167 pred_newerXY (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1171 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
1173 switch (pred_ptr
->args
.reftime
.xval
)
1176 ts
= get_stat_atime(stat_buf
);
1178 case XVAL_BIRTHTIME
:
1179 assert(pred_ptr
->args
.reftime
.xval
!= XVAL_BIRTHTIME
); /* Unsupported. */
1184 ts
= get_stat_ctime(stat_buf
);
1187 ts
= get_stat_mtime(stat_buf
);
1190 assert(pred_ptr
->args
.reftime
.xval
!= XVAL_TIME
);
1194 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) > 0;
1198 pred_nogroup (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1204 extern char *gid_unused
;
1206 return gid_unused
[(unsigned) stat_buf
->st_gid
];
1208 return getgrgid (stat_buf
->st_gid
) == NULL
;
1213 pred_nouser (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1216 extern char *uid_unused
;
1223 return uid_unused
[(unsigned) stat_buf
->st_uid
];
1225 return getpwuid (stat_buf
->st_uid
) == NULL
;
1231 is_ok(const char *program
, const char *arg
)
1234 /* The draft open standard requires that, in the POSIX locale,
1235 the last non-blank character of this prompt be '?'.
1236 The exact format is not specified.
1237 This standard does not have requirements for locales other than POSIX
1239 /* XXX: printing UNTRUSTED data here. */
1240 fprintf (stderr
, _("< %s ... %s > ? "), program
, arg
);
1246 pred_ok (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1248 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1249 return new_impl_pred_exec (pathname
, stat_buf
, pred_ptr
, NULL
, 0);
1255 pred_okdir (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1257 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
1258 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1259 return new_impl_pred_exec (state
.rel_pathname
, stat_buf
, pred_ptr
,
1260 prefix
, (prefix
? 2 : 0));
1266 pred_open (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1275 pred_or (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1277 if (pred_ptr
->pred_left
== NULL
1278 || !(*pred_ptr
->pred_left
->pred_func
) (pathname
, stat_buf
,
1279 pred_ptr
->pred_left
))
1281 if (get_info(pathname
, state
.rel_pathname
, stat_buf
, pred_ptr
) != 0)
1283 return ((*pred_ptr
->pred_right
->pred_func
) (pathname
, stat_buf
,
1284 pred_ptr
->pred_right
));
1291 pred_path (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1294 if (fnmatch (pred_ptr
->args
.str
, pathname
, 0) == 0)
1300 pred_perm (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1302 mode_t mode
= stat_buf
->st_mode
;
1303 mode_t perm_val
= pred_ptr
->args
.perm
.val
[S_ISDIR (mode
) != 0];
1305 switch (pred_ptr
->args
.perm
.kind
)
1308 return (mode
& perm_val
) == perm_val
;
1312 /* True if any of the bits set in the mask are also set in the file's mode.
1315 * Otherwise, if onum is prefixed by a hyphen, the primary shall
1316 * evaluate as true if at least all of the bits specified in
1317 * onum that are also set in the octal mask 07777 are set.
1319 * Eric Blake's interpretation is that the mode argument is zero,
1323 return true; /* Savannah bug 14748; we used to return false */
1325 return (mode
& perm_val
) != 0;
1329 return (mode
& MODE_ALL
) == perm_val
;
1340 pred_executable (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1346 return 0 == access(state
.rel_pathname
, X_OK
);
1350 pred_readable (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1356 return 0 == access(state
.rel_pathname
, R_OK
);
1360 pred_writable (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1366 return 0 == access(state
.rel_pathname
, W_OK
);
1370 pred_print (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1374 /* puts (pathname); */
1375 print_quoted(pred_ptr
->args
.printf_vec
.stream
,
1376 pred_ptr
->args
.printf_vec
.quote_opts
,
1377 pred_ptr
->args
.printf_vec
.dest_is_tty
,
1383 pred_print0 (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1387 fputs (pathname
, stdout
);
1393 pred_prune (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1398 if (options
.do_dir_first
== true &&
1400 S_ISDIR(stat_buf
->st_mode
))
1401 state
.stop_at_current_level
= true;
1403 return (options
.do_dir_first
); /* This is what SunOS find seems to do. */
1407 pred_quit (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1413 /* Run any cleanups. This includes executing any command lines
1414 * we have partly built but not executed.
1418 /* Since -exec and friends don't leave child processes running in the
1419 * background, there is no need to wait for them here.
1421 exit(state
.exit_status
); /* 0 for success, etc. */
1425 pred_regex (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1427 int len
= strlen (pathname
);
1429 if (re_match (pred_ptr
->args
.regex
, pathname
, len
, 0,
1430 (struct re_registers
*) NULL
) == len
)
1436 pred_size (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1441 f_val
= ((stat_buf
->st_size
/ pred_ptr
->args
.size
.blocksize
)
1442 + (stat_buf
->st_size
% pred_ptr
->args
.size
.blocksize
!= 0));
1443 switch (pred_ptr
->args
.size
.kind
)
1446 if (f_val
> pred_ptr
->args
.size
.size
)
1450 if (f_val
< pred_ptr
->args
.size
.size
)
1454 if (f_val
== pred_ptr
->args
.size
.size
)
1462 pred_samefile (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1464 /* Potential optimisation: because of the loop protection, we always
1465 * know the device of the current directory, hence the device number
1466 * of the file we're currently considering. If -L is not in effect,
1467 * and the device number of the file we're looking for is not the
1468 * same as the device number of the current directory, this
1469 * predicate cannot return true. Hence there would be no need to
1470 * stat the file we're looking at.
1474 return stat_buf
->st_ino
== pred_ptr
->args
.fileid
.ino
1475 && stat_buf
->st_dev
== pred_ptr
->args
.fileid
.dev
;
1479 pred_true (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1488 pred_type (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1491 mode_t type
= pred_ptr
->args
.type
;
1493 assert(state
.have_type
);
1494 assert(state
.type
!= 0);
1498 if (state
.have_stat
)
1499 mode
= stat_buf
->st_mode
;
1504 /* POSIX system; check `mode' the slow way. */
1505 if ((S_ISBLK (mode
) && type
== S_IFBLK
)
1506 || (S_ISCHR (mode
) && type
== S_IFCHR
)
1507 || (S_ISDIR (mode
) && type
== S_IFDIR
)
1508 || (S_ISREG (mode
) && type
== S_IFREG
)
1510 || (S_ISLNK (mode
) && type
== S_IFLNK
)
1513 || (S_ISFIFO (mode
) && type
== S_IFIFO
)
1516 || (S_ISSOCK (mode
) && type
== S_IFSOCK
)
1519 || (S_ISDOOR (mode
) && type
== S_IFDOOR
)
1523 /* Unix system; check `mode' the fast way. */
1524 if ((mode
& S_IFMT
) == type
)
1532 pred_uid (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1535 switch (pred_ptr
->args
.numinfo
.kind
)
1538 if (stat_buf
->st_uid
> pred_ptr
->args
.numinfo
.l_val
)
1542 if (stat_buf
->st_uid
< pred_ptr
->args
.numinfo
.l_val
)
1546 if (stat_buf
->st_uid
== pred_ptr
->args
.numinfo
.l_val
)
1554 pred_used (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1556 struct timespec delta
, at
, ct
;
1560 /* TODO: this needs to be retested carefully (manually, if necessary) */
1561 at
= get_stat_atime(stat_buf
);
1562 ct
= get_stat_ctime(stat_buf
);
1563 delta
.tv_sec
= at
.tv_sec
- ct
.tv_sec
;
1564 delta
.tv_nsec
= at
.tv_nsec
- ct
.tv_nsec
;
1565 if (delta
.tv_nsec
< 0)
1567 delta
.tv_nsec
+= 1000000000;
1570 return pred_timewindow(delta
, pred_ptr
, DAYSECS
);
1574 pred_user (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1577 if (pred_ptr
->args
.uid
== stat_buf
->st_uid
)
1584 pred_xtype (char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1586 struct stat sbuf
; /* local copy, not stat_buf because we're using a different stat method */
1587 int (*ystat
) (const char*, struct stat
*p
);
1589 /* If we would normally stat the link itself, stat the target instead.
1590 * If we would normally follow the link, stat the link itself instead.
1592 if (following_links())
1593 ystat
= optionp_stat
;
1595 ystat
= optionl_stat
;
1597 if ((*ystat
) (state
.rel_pathname
, &sbuf
) != 0)
1599 if (following_links() && errno
== ENOENT
)
1601 /* If we failed to follow the symlink,
1602 * fall back on looking at the symlink itself.
1604 /* Mimic behavior of ls -lL. */
1605 return (pred_type (pathname
, stat_buf
, pred_ptr
));
1609 error (0, errno
, "%s", pathname
);
1610 state
.exit_status
= 1;
1614 /* Now that we have our stat() information, query it in the same
1615 * way that -type does.
1617 return (pred_type (pathname
, &sbuf
, pred_ptr
));
1620 /* 1) fork to get a child; parent remembers the child pid
1621 2) child execs the command requested
1622 3) parent waits for child; checks for proper pid of child
1626 ret errno status(h) status(l)
1628 pid x signal# 0177 stopped
1629 pid x exit arg 0 term by _exit
1630 pid x 0 signal # term by signal
1631 -1 EINTR parent got signal
1632 -1 other some other kind of error
1634 Return true only if the pid matches, status(l) is
1635 zero, and the exit arg (status high) is 0.
1636 Otherwise return false, possibly printing an error message. */
1640 prep_child_for_exec (boolean close_stdin
)
1644 const char inputfile
[] = "/dev/null";
1645 /* fprintf(stderr, "attaching stdin to /dev/null\n"); */
1648 if (open(inputfile
, O_RDONLY
) < 0)
1650 /* This is not entirely fatal, since
1651 * executing the child with a closed
1652 * stdin is almost as good as executing it
1653 * with its stdin attached to /dev/null.
1655 error (0, errno
, "%s", inputfile
);
1663 launch (const struct buildcmd_control
*ctl
,
1664 struct buildcmd_state
*buildstate
)
1668 static int first_time
= 1;
1669 const struct exec_val
*execp
= buildstate
->usercontext
;
1671 /* Null terminate the arg list. */
1672 bc_push_arg (ctl
, buildstate
, (char *) NULL
, 0, NULL
, 0, false);
1674 /* Make sure output of command doesn't get mixed with find output. */
1678 /* Make sure to listen for the kids. */
1682 signal (SIGCHLD
, SIG_DFL
);
1685 child_pid
= fork ();
1686 if (child_pid
== -1)
1687 error (1, errno
, _("cannot fork"));
1690 /* We be the child. */
1691 prep_child_for_exec(execp
->close_stdin
);
1693 /* For -exec and -ok, change directory back to the starting directory.
1694 * for -execdir and -okdir, stay in the directory we are searching
1695 * (the latter is more secure).
1697 if (!execp
->use_current_dir
)
1699 /* Even if DebugSearch is set, don't announce our change of
1700 * directory, since we're not going to emit a subsequent
1701 * announcement of a call to stat() anyway, as we're about
1702 * to exec something.
1704 if (starting_desc
< 0
1705 ? chdir (starting_dir
) != 0
1706 : fchdir (starting_desc
) != 0)
1708 error (0, errno
, "%s", starting_dir
);
1713 execvp (buildstate
->cmd_argv
[0], buildstate
->cmd_argv
);
1714 error (0, errno
, "%s", buildstate
->cmd_argv
[0]);
1719 /* In parent; set up for next time. */
1720 bc_clear_args(ctl
, buildstate
);
1723 while (waitpid (child_pid
, &wait_status
, 0) == (pid_t
) -1)
1727 error (0, errno
, _("error waiting for %s"), buildstate
->cmd_argv
[0]);
1728 state
.exit_status
= 1;
1729 return 0; /* FAIL */
1733 if (WIFSIGNALED (wait_status
))
1735 error (0, 0, _("%s terminated by signal %d"),
1736 buildstate
->cmd_argv
[0], WTERMSIG (wait_status
));
1738 if (execp
->multiple
)
1740 /* -exec \; just returns false if the invoked command fails.
1741 * -exec {} + returns true if the invoked command fails, but
1742 * sets the program exit status.
1744 state
.exit_status
= 1;
1750 if (0 == WEXITSTATUS (wait_status
))
1756 if (execp
->multiple
)
1758 /* -exec \; just returns false if the invoked command fails.
1759 * -exec {} + returns true if the invoked command fails, but
1760 * sets the program exit status.
1762 state
.exit_status
= 1;
1764 return 0; /* FAIL */
1770 /* Return a static string formatting the time WHEN according to the
1771 * strftime format character KIND.
1773 * This function contains a number of assertions. These look like
1774 * runtime checks of the results of computations, which would be a
1775 * problem since external events should not be tested for with
1776 * "assert" (instead you should use "if"). However, they are not
1777 * really runtime checks. The assertions actually exist to verify
1778 * that the various buffers are correctly sized.
1781 format_date (struct timespec ts
, int kind
)
1783 /* Use an extra 10 characters for 9 digits of nanoseconds and 1 for
1788 DATE_LEN_PERCENT_APLUS
=21 /* length of result of %A+ (it's longer than %c)*/
1790 static char buf
[10u + MAX(DATE_LEN_PERCENT_APLUS
, MAX (LONGEST_HUMAN_READABLE
+ 2, 64))];
1791 char ns_buf
[NS_BUF_LEN
]; /* .9999999990 */
1792 int charsprinted
, need_ns_suffix
;
1796 /* human_readable() assumes we pass a buffer which is at least as
1797 * long as LONGEST_HUMAN_READABLE. We use an assertion here to
1798 * ensure that no nasty unsigned overflow happend in our calculation
1799 * of the size of buf. Do the assertion here rather than in the
1800 * code for %@ so that we find the problem quickly if it exists. If
1801 * you want to submit a patch to move this into the if statement, go
1802 * ahead, I'll apply it. But include performance timings
1803 * demonstrating that the performance difference is actually
1806 assert(sizeof(buf
) >= LONGEST_HUMAN_READABLE
);
1808 /* Format the main part of the time. */
1811 strcpy (fmt
, "%F+%T");
1820 /* %a, %c, and %t are handled in ctime_format() */
1836 /* Format the nanoseconds part. Leave a trailing zero to discourage people from
1837 * writing scripts which extract the fractional part of the timestamp by using
1838 * column offsets. The reason for discouraging this is that in the future, the
1839 * granularity may not be nanoseconds.
1841 charsprinted
= snprintf(ns_buf
, NS_BUF_LEN
, ".%09ld0", (long int)ts
.tv_nsec
);
1842 assert(charsprinted
< NS_BUF_LEN
);
1846 && (tm
= localtime (&ts
.tv_sec
))
1847 && strftime (buf
, sizeof buf
, fmt
, tm
))
1849 /* For %AS, %CS, %TS, add the fractional part of the seconds information. */
1852 assert((sizeof buf
- strlen(buf
)) > strlen(ns_buf
));
1853 strcat(buf
, ns_buf
);
1859 uintmax_t w
= ts
.tv_sec
;
1860 size_t used
, len
, remaining
;
1862 /* XXX: note that we are negating an unsigned type which is the
1863 * widest possible unsigned type.
1865 char *p
= human_readable (ts
.tv_sec
< 0 ? -w
: w
, buf
+ 1,
1866 human_ceiling
, 1, 1);
1868 assert(p
< (buf
+ (sizeof buf
)));
1870 *--p
= '-'; /* XXX: Ugh, relying on internal details of human_readable(). */
1872 /* Add the nanoseconds part. Because we cannot enforce a particlar implementation
1873 * of human_readable, we cannot assume any particular value for (p-buf). So we
1874 * need to be careful that there is enough space remaining in the buffer.
1877 used
= (p
-buf
) + len
; /* Offset into buf of current end */
1878 assert(sizeof buf
> used
); /* Ensure we can perform subtraction safely. */
1879 remaining
= sizeof buf
- used
- 1u; /* allow space for NUL */
1880 assert(strlen(ns_buf
) < remaining
);
1886 static const char *weekdays
[] =
1888 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
1890 static char * months
[] =
1892 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1893 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1898 ctime_format (struct timespec ts
)
1900 const struct tm
* ptm
;
1901 #define TIME_BUF_LEN 1024u
1902 static char resultbuf
[TIME_BUF_LEN
];
1905 ptm
= localtime(&ts
.tv_sec
);
1908 assert(ptm
->tm_wday
>= 0);
1909 assert(ptm
->tm_wday
< 7);
1910 assert(ptm
->tm_mon
>= 0);
1911 assert(ptm
->tm_mon
< 12);
1912 assert(ptm
->tm_hour
>= 0);
1913 assert(ptm
->tm_hour
< 24);
1914 assert(ptm
->tm_min
< 60);
1915 assert(ptm
->tm_sec
<= 61); /* allows 2 leap seconds. */
1917 /* wkday mon mday hh:mm:ss.nnnnnnnnn yyyy */
1918 nout
= snprintf(resultbuf
, TIME_BUF_LEN
,
1919 "%3s %3s %2d %02d:%02d:%02d.%010ld %04d",
1920 weekdays
[ptm
->tm_wday
],
1921 months
[ptm
->tm_mon
],
1926 (long int)ts
.tv_nsec
,
1927 1900 + ptm
->tm_year
);
1929 assert(nout
< TIME_BUF_LEN
);
1934 /* The time cannot be represented as a struct tm.
1935 Output it as an integer. */
1936 return format_date (ts
, '@');
1940 /* Copy STR into BUF and trim blanks from the end of BUF.
1944 blank_rtrim (str
, buf
)
1953 i
= strlen (buf
) - 1;
1954 while ((i
>= 0) && ((buf
[i
] == ' ') || buf
[i
] == '\t'))
1960 /* Print out the predicate list starting at NODE. */
1962 print_list (FILE *fp
, struct predicate
*node
)
1964 struct predicate
*cur
;
1970 fprintf (fp
, "%s ", blank_rtrim (cur
->p_name
, name
));
1971 cur
= cur
->pred_next
;
1976 /* Print out the predicate list starting at NODE. */
1978 print_parenthesised(FILE *fp
, struct predicate
*node
)
1984 if ( ( (node
->pred_func
== pred_or
)
1985 || (node
->pred_func
== pred_and
) )
1986 && node
->pred_left
== NULL
)
1988 /* We print "<nothing> or X" as just "X"
1989 * We print "<nothing> and X" as just "X"
1991 print_parenthesised(fp
, node
->pred_right
);
1995 if (node
->pred_left
|| node
->pred_right
)
1999 fprintf(fp
, "%s", " ( ");
2000 print_optlist(fp
, node
);
2002 fprintf(fp
, "%s", " ) ");
2008 print_optlist (FILE *fp
, const struct predicate
*p
)
2012 print_parenthesised(fp
, p
->pred_left
);
2015 p
->need_stat
? "[call stat] " : "",
2016 p
->need_type
? "[need type] " : "");
2017 print_predicate(fp
, p
);
2018 fprintf(fp
, " [%g] ", p
->est_success_rate
);
2019 print_parenthesised(fp
, p
->pred_right
);
2024 /* If _NDEBUG is defined, the assertions will do nothing. Hence
2025 * there is no point in having a function body for pred_sanity_check()
2026 * if that preprocessor macro is defined.
2029 pred_sanity_check(const struct predicate
*predicates
)
2031 /* Do nothing, since assert() is a no-op with _NDEBUG set */
2036 pred_sanity_check(const struct predicate
*predicates
)
2038 const struct predicate
*p
;
2040 for (p
=predicates
; p
!= NULL
; p
=p
->pred_next
)
2042 /* All predicates must do something. */
2043 assert(p
->pred_func
!= NULL
);
2045 /* All predicates must have a parser table entry. */
2046 assert(p
->parser_entry
!= NULL
);
2048 /* If the parser table tells us that just one predicate function is
2049 * possible, verify that that is still the one that is in effect.
2050 * If the parser has NULL for the predicate function, that means that
2051 * the parse_xxx function fills it in, so we can't check it.
2053 if (p
->parser_entry
->pred_func
)
2055 assert(p
->parser_entry
->pred_func
== p
->pred_func
);
2058 switch (p
->parser_entry
->type
)
2060 /* Options all take effect during parsing, so there should
2061 * be no predicate entries corresponding to them. Hence we
2062 * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
2065 * This is a silly way of coding this test, but it prevents
2066 * a compiler warning (i.e. otherwise it would think that
2067 * there would be case statements missing).
2070 case ARG_POSITIONAL_OPTION
:
2071 assert(p
->parser_entry
->type
!= ARG_OPTION
);
2072 assert(p
->parser_entry
->type
!= ARG_POSITIONAL_OPTION
);
2076 assert(p
->side_effects
); /* actions have side effects. */
2077 if (p
->pred_func
!= pred_prune
&& p
->pred_func
!= pred_quit
)
2079 /* actions other than -prune and -quit should
2080 * inhibit the default -print
2082 assert(p
->no_default_print
);
2086 case ARG_PUNCTUATION
:
2089 /* Punctuation and tests should have no side
2090 * effects and not inhibit default print.
2092 assert(!p
->no_default_print
);
2093 assert(!p
->side_effects
);