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>
40 #include "printquoted.h"
44 #include "stat-time.h"
45 #include "dircallback.h"
50 # define _(Text) gettext (Text)
55 # define N_(String) gettext_noop (String)
57 /* See locate.c for explanation as to why not use (String) */
58 # define N_(String) String
61 #if !defined(SIGCHLD) && defined(SIGCLD)
62 #define SIGCHLD SIGCLD
69 # define NAMLEN(dirent) strlen((dirent)->d_name)
71 # define dirent direct
72 # define NAMLEN(dirent) (dirent)->d_namlen
74 # include <sys/ndir.h>
85 /* Fake a return value. */
86 #define CLOSEDIR(d) (closedir (d), 0)
88 #define CLOSEDIR(d) closedir (d)
94 /* Get or fake the disk device blocksize.
95 Usually defined by sys/param.h (if at all). */
98 # define DEV_BSIZE BSIZE
100 # define DEV_BSIZE 4096
102 #endif /* !DEV_BSIZE */
104 /* Extract or fake data from a `struct stat'.
105 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
106 ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
107 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
108 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
109 # define ST_BLKSIZE(statbuf) DEV_BSIZE
110 # if defined(_POSIX_SOURCE) || !defined(BSIZE) /* fileblocks.c uses BSIZE. */
111 # define ST_NBLOCKS(statbuf) \
112 (S_ISREG ((statbuf).st_mode) \
113 || S_ISDIR ((statbuf).st_mode) \
114 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
115 # else /* !_POSIX_SOURCE && BSIZE */
116 # define ST_NBLOCKS(statbuf) \
117 (S_ISREG ((statbuf).st_mode) \
118 || S_ISDIR ((statbuf).st_mode) \
119 ? st_blocks ((statbuf).st_size) : 0)
120 # endif /* !_POSIX_SOURCE && BSIZE */
121 #else /* HAVE_STRUCT_STAT_ST_BLOCKS */
122 /* Some systems, like Sequents, return st_blksize of 0 on pipes. */
123 # define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
124 ? (statbuf).st_blksize : DEV_BSIZE)
125 # if defined(hpux) || defined(__hpux__) || defined(__hpux)
126 /* HP-UX counts st_blocks in 1024-byte units.
127 This loses when mixing HP-UX and BSD filesystems with NFS. */
128 # define ST_NBLOCKSIZE 1024
130 # if defined(_AIX) && defined(_I386)
131 /* AIX PS/2 counts st_blocks in 4K units. */
132 # define ST_NBLOCKSIZE (4 * 1024)
133 # else /* not AIX PS/2 */
135 # define ST_NBLOCKS(statbuf) \
136 (S_ISREG ((statbuf).st_mode) \
137 || S_ISDIR ((statbuf).st_mode) \
138 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
140 # endif /* not AIX PS/2 */
142 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
145 # define ST_NBLOCKS(statbuf) \
146 (S_ISREG ((statbuf).st_mode) \
147 || S_ISDIR ((statbuf).st_mode) \
148 ? (statbuf).st_blocks : 0)
151 #ifndef ST_NBLOCKSIZE
152 # define ST_NBLOCKSIZE 512
157 #define MAX(a, b) ((a) > (b) ? (a) : (b))
159 static boolean match_lname
PARAMS((const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
));
161 static char *format_date
PARAMS((struct timespec ts
, int kind
));
162 static char *ctime_format
PARAMS((struct timespec ts
));
171 struct pred_assoc pred_table
[] =
173 {pred_amin
, "amin "},
175 {pred_anewer
, "anewer "},
176 {pred_atime
, "atime "},
177 {pred_closeparen
, ") "},
178 {pred_cmin
, "cmin "},
179 {pred_cnewer
, "cnewer "},
181 {pred_ctime
, "ctime "},
182 {pred_delete
, "delete "},
183 {pred_empty
, "empty "},
184 {pred_exec
, "exec "},
185 {pred_execdir
, "execdir "},
186 {pred_executable
, "executable "},
187 {pred_false
, "false "},
188 {pred_fprint
, "fprint "},
189 {pred_fprint0
, "fprint0 "},
190 {pred_fprintf
, "fprintf "},
191 {pred_fstype
, "fstype "},
193 {pred_group
, "group "},
194 {pred_ilname
, "ilname "},
195 {pred_iname
, "iname "},
196 {pred_inum
, "inum "},
197 {pred_ipath
, "ipath "},
198 {pred_links
, "links "},
199 {pred_lname
, "lname "},
201 {pred_mmin
, "mmin "},
202 {pred_mtime
, "mtime "},
203 {pred_name
, "name "},
204 {pred_negate
, "not "},
205 {pred_newer
, "newer "},
206 {pred_newerXY
, "newerXY "},
207 {pred_nogroup
, "nogroup "},
208 {pred_nouser
, "nouser "},
210 {pred_okdir
, "okdir "},
211 {pred_openparen
, "( "},
213 {pred_path
, "path "},
214 {pred_perm
, "perm "},
215 {pred_print
, "print "},
216 {pred_print0
, "print0 "},
217 {pred_prune
, "prune "},
218 {pred_quit
, "quit "},
219 {pred_readable
, "readable "},
220 {pred_regex
, "regex "},
221 {pred_samefile
,"samefile "},
222 {pred_size
, "size "},
223 {pred_true
, "true "},
224 {pred_type
, "type "},
226 {pred_used
, "used "},
227 {pred_user
, "user "},
228 {pred_writable
, "writable "},
229 {pred_xtype
, "xtype "},
234 /* Returns ts1 - ts2 */
235 static double ts_difference(struct timespec ts1
,
238 double d
= difftime(ts1
.tv_sec
, ts2
.tv_sec
)
239 + (1.0e-9 * (ts1
.tv_nsec
- ts2
.tv_nsec
));
245 compare_ts(struct timespec ts1
,
248 if ((ts1
.tv_sec
== ts2
.tv_sec
) &&
249 (ts1
.tv_nsec
== ts2
.tv_nsec
))
255 double diff
= ts_difference(ts1
, ts2
);
256 return diff
< 0.0 ? -1 : +1;
260 /* Predicate processing routines.
262 PATHNAME is the full pathname of the file being checked.
263 *STAT_BUF contains information about PATHNAME.
264 *PRED_PTR contains information for applying the predicate.
266 Return true if the file passes this predicate, false if not. */
271 * Returns true if THE_TIME is
272 * COMP_GT: after the specified time
273 * COMP_LT: before the specified time
274 * COMP_EQ: less than WINDOW seconds after the specified time.
277 pred_timewindow(struct timespec ts
, struct predicate
const *pred_ptr
, int window
)
279 switch (pred_ptr
->args
.reftime
.kind
)
282 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) > 0;
285 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) < 0;
289 double delta
= ts_difference(ts
, pred_ptr
->args
.reftime
.ts
);
290 return (delta
>= 0.0 && delta
< window
);
297 pred_amin (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
300 return pred_timewindow(get_stat_atime(stat_buf
), pred_ptr
, 60);
304 pred_and (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
306 if (pred_ptr
->pred_left
== NULL
307 || apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_left
))
309 return apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_right
);
316 pred_anewer (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
319 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
320 return compare_ts(get_stat_atime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
324 pred_atime (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
327 return pred_timewindow(get_stat_atime(stat_buf
), pred_ptr
, DAYSECS
);
331 pred_closeparen (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
341 pred_cmin (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
344 return pred_timewindow(get_stat_ctime(stat_buf
), pred_ptr
, 60);
348 pred_cnewer (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
352 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
353 return compare_ts(get_stat_ctime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
357 pred_comma (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
359 if (pred_ptr
->pred_left
!= NULL
)
361 apply_predicate(pathname
, stat_buf
,pred_ptr
->pred_left
);
363 return apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_right
);
367 pred_ctime (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
370 return pred_timewindow(get_stat_ctime(stat_buf
), pred_ptr
, DAYSECS
);
374 perform_delete(int flags
)
376 return 0 == unlinkat(state
.cwd_dir_fd
, state
.rel_pathname
, flags
);
381 pred_delete (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
385 if (strcmp (state
.rel_pathname
, "."))
388 if (state
.have_stat
&& S_ISDIR(stat_buf
->st_mode
))
389 flags
|= AT_REMOVEDIR
;
390 if (perform_delete(flags
))
398 if ((flags
& AT_REMOVEDIR
) == 0)
400 /* unlink() operation failed because we should have done rmdir(). */
401 flags
|= AT_REMOVEDIR
;
402 if (perform_delete(flags
))
407 error (0, errno
, "cannot delete %s",
408 safely_quote_err_filename(0, pathname
));
419 pred_empty (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
424 if (S_ISDIR (stat_buf
->st_mode
))
429 boolean empty
= true;
432 if ((fd
= openat(state
.cwd_dir_fd
, state
.rel_pathname
, O_RDONLY
433 #if defined O_LARGEFILE
438 error (0, errno
, "%s", safely_quote_err_filename(0, pathname
));
439 state
.exit_status
= 1;
445 error (0, errno
, "%s", safely_quote_err_filename(0, pathname
));
446 state
.exit_status
= 1;
449 for (dp
= readdir (d
); dp
; dp
= readdir (d
))
451 if (dp
->d_name
[0] != '.'
452 || (dp
->d_name
[1] != '\0'
453 && (dp
->d_name
[1] != '.' || dp
->d_name
[2] != '\0')))
461 error (0, errno
, "%s", safely_quote_err_filename(0, pathname
));
462 state
.exit_status
= 1;
467 else if (S_ISREG (stat_buf
->st_mode
))
468 return (stat_buf
->st_size
== 0);
474 new_impl_pred_exec (int dirfd
, const char *pathname
,
475 struct stat
*stat_buf
,
476 struct predicate
*pred_ptr
,
477 const char *prefix
, size_t pfxlen
)
479 struct exec_val
*execp
= &pred_ptr
->args
.exec_vec
;
480 size_t len
= strlen(pathname
);
483 execp
->dirfd
= dirfd
;
486 /* Push the argument onto the current list.
487 * The command may or may not be run at this point,
488 * depending on the command line length limits.
490 bc_push_arg(&execp
->ctl
,
496 /* remember that there are pending execdirs. */
497 state
.execdirs_outstanding
= true;
499 /* POSIX: If the primary expression is punctuated by a plus
500 * sign, the primary shall always evaluate as true
508 for (i
=0; i
<execp
->num_args
; ++i
)
510 bc_do_insert(&execp
->ctl
,
512 execp
->replace_vec
[i
],
513 strlen(execp
->replace_vec
[i
]),
519 /* Actually invoke the command. */
520 return execp
->ctl
.exec_callback(&execp
->ctl
,
527 pred_exec (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
529 return new_impl_pred_exec(get_start_dirfd(),
530 pathname
, stat_buf
, pred_ptr
, NULL
, 0);
534 pred_execdir (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
536 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
538 return new_impl_pred_exec (get_current_dirfd(),
539 state
.rel_pathname
, stat_buf
, pred_ptr
,
540 prefix
, (prefix
? 2 : 0));
544 pred_false (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
555 pred_fls (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
557 list_file (pathname
, state
.cwd_dir_fd
, state
.rel_pathname
, stat_buf
, options
.start_time
.tv_sec
,
558 options
.output_block_size
,
559 pred_ptr
->literal_control_chars
, pred_ptr
->args
.stream
);
564 pred_fprint (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
569 print_quoted(pred_ptr
->args
.printf_vec
.stream
,
570 pred_ptr
->args
.printf_vec
.quote_opts
,
571 pred_ptr
->args
.printf_vec
.dest_is_tty
,
578 pred_fprint0 (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
583 fputs (pathname
, pred_ptr
->args
.stream
);
584 putc (0, pred_ptr
->args
.stream
);
591 mode_to_filetype(mode_t m
)
594 m
== S_IFSOCK
? "s" :
601 m
== S_IFDOOR
? "D" :
603 m
== S_IFIFO
? "p" : "U";
607 file_sparseness(const struct stat
*p
)
611 if (0 == p
->st_blocks
)
614 return p
->st_blocks
< 0 ? -HUGE_VAL
: HUGE_VAL
;
618 double blklen
= file_blocksize(p
) * (double)p
->st_blocks
;
619 return blklen
/ p
->st_size
;
627 struct segment
*segment
,
628 const char *pathname
,
629 const struct stat
*stat_buf
,
631 const struct quoting_options
*qopts
)
633 char hbuf
[LONGEST_HUMAN_READABLE
+ 1];
636 switch (segment
->segkind
)
638 case KIND_PLAIN
: /* Plain text string (no % conversion). */
640 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
643 case KIND_STOP
: /* Terminate argument and flush output. */
645 fwrite (segment
->text
, 1, segment
->text_len
, fp
);
650 switch (segment
->format_char
[0])
652 case 'a': /* atime in `ctime' format. */
653 /* UNTRUSTED, probably unexploitable */
654 fprintf (fp
, segment
->text
, ctime_format (get_stat_atime(stat_buf
)));
656 case 'b': /* size in 512-byte blocks */
657 /* UNTRUSTED, probably unexploitable */
658 fprintf (fp
, segment
->text
,
659 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
661 ST_NBLOCKSIZE
, 512));
663 case 'c': /* ctime in `ctime' format */
664 /* UNTRUSTED, probably unexploitable */
665 fprintf (fp
, segment
->text
, ctime_format (get_stat_ctime(stat_buf
)));
667 case 'd': /* depth in search tree */
668 /* UNTRUSTED, probably unexploitable */
669 fprintf (fp
, segment
->text
, state
.curdepth
);
671 case 'D': /* Device on which file exists (stat.st_dev) */
673 fprintf (fp
, segment
->text
,
674 human_readable ((uintmax_t) stat_buf
->st_dev
, hbuf
,
675 human_ceiling
, 1, 1));
677 case 'f': /* base name of path */
679 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, base_name (pathname
));
681 case 'F': /* filesystem type */
683 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, filesystem_type (stat_buf
, pathname
));
685 case 'g': /* group name */
687 /* (well, the actual group is selected by the user but
688 * its name was selected by the system administrator)
693 g
= getgrgid (stat_buf
->st_gid
);
696 segment
->text
[segment
->text_len
] = 's';
697 fprintf (fp
, segment
->text
, g
->gr_name
);
706 case 'G': /* GID number */
707 /* UNTRUSTED, probably unexploitable */
708 fprintf (fp
, segment
->text
,
709 human_readable ((uintmax_t) stat_buf
->st_gid
, hbuf
,
710 human_ceiling
, 1, 1));
712 case 'h': /* leading directories part of path */
715 cp
= strrchr (pathname
, '/');
716 if (cp
== NULL
) /* No leading directories. */
718 /* If there is no slash in the pathname, we still
719 * print the string because it contains characters
720 * other than just '%s'. The %h expands to ".".
722 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, ".");
726 char *s
= strdup(pathname
);
727 s
[cp
- pathname
] = 0;
728 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, s
);
733 case 'H': /* ARGV element file was found under */
736 char *s
= xmalloc(state
.starting_path_length
+1);
737 memcpy(s
, pathname
, state
.starting_path_length
);
738 s
[state
.starting_path_length
] = 0;
739 fprintf (fp
, segment
->text
, s
);
743 case 'i': /* inode number */
744 /* UNTRUSTED, but not exploitable I think */
745 fprintf (fp
, segment
->text
,
746 human_readable ((uintmax_t) stat_buf
->st_ino
, hbuf
,
750 case 'k': /* size in 1K blocks */
751 /* UNTRUSTED, but not exploitable I think */
752 fprintf (fp
, segment
->text
,
753 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf
),
755 ST_NBLOCKSIZE
, 1024));
757 case 'l': /* object of symlink */
763 if (S_ISLNK (stat_buf
->st_mode
))
765 linkname
= get_link_name_at (pathname
, state
.cwd_dir_fd
, state
.rel_pathname
);
767 state
.exit_status
= 1;
771 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, linkname
);
776 /* We still need to honour the field width etc., so this is
779 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, "");
785 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */
786 /* UNTRUSTED, probably unexploitable */
788 char modestring
[16] ;
789 filemodestring (stat_buf
, modestring
);
790 modestring
[10] = '\0';
791 fprintf (fp
, segment
->text
, modestring
);
795 case 'm': /* mode as octal number (perms only) */
796 /* UNTRUSTED, probably unexploitable */
798 /* Output the mode portably using the traditional numbers,
799 even if the host unwisely uses some other numbering
800 scheme. But help the compiler in the common case where
801 the host uses the traditional numbering scheme. */
802 mode_t m
= stat_buf
->st_mode
;
803 boolean traditional_numbering_scheme
=
804 (S_ISUID
== 04000 && S_ISGID
== 02000 && S_ISVTX
== 01000
805 && S_IRUSR
== 00400 && S_IWUSR
== 00200 && S_IXUSR
== 00100
806 && S_IRGRP
== 00040 && S_IWGRP
== 00020 && S_IXGRP
== 00010
807 && S_IROTH
== 00004 && S_IWOTH
== 00002 && S_IXOTH
== 00001);
808 fprintf (fp
, segment
->text
,
809 (traditional_numbering_scheme
811 : ((m
& S_ISUID
? 04000 : 0)
812 | (m
& S_ISGID
? 02000 : 0)
813 | (m
& S_ISVTX
? 01000 : 0)
814 | (m
& S_IRUSR
? 00400 : 0)
815 | (m
& S_IWUSR
? 00200 : 0)
816 | (m
& S_IXUSR
? 00100 : 0)
817 | (m
& S_IRGRP
? 00040 : 0)
818 | (m
& S_IWGRP
? 00020 : 0)
819 | (m
& S_IXGRP
? 00010 : 0)
820 | (m
& S_IROTH
? 00004 : 0)
821 | (m
& S_IWOTH
? 00002 : 0)
822 | (m
& S_IXOTH
? 00001 : 0))));
826 case 'n': /* number of links */
827 /* UNTRUSTED, probably unexploitable */
828 fprintf (fp
, segment
->text
,
829 human_readable ((uintmax_t) stat_buf
->st_nlink
,
834 case 'p': /* pathname */
836 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, pathname
);
838 case 'P': /* pathname with ARGV element stripped */
840 if (state
.curdepth
> 0)
842 cp
= pathname
+ state
.starting_path_length
;
844 /* Move past the slash between the ARGV element
845 and the rest of the pathname. But if the ARGV element
846 ends in a slash, we didn't add another, so we've
847 already skipped past it. */
852 print_quoted (fp
, qopts
, ttyflag
, segment
->text
, cp
);
854 case 's': /* size in bytes */
855 /* UNTRUSTED, probably unexploitable */
856 fprintf (fp
, segment
->text
,
857 human_readable ((uintmax_t) stat_buf
->st_size
,
858 hbuf
, human_ceiling
, 1, 1));
861 case 'S': /* sparseness */
862 /* UNTRUSTED, probably unexploitable */
863 fprintf (fp
, segment
->text
, file_sparseness(stat_buf
));;
866 case 't': /* mtime in `ctime' format */
867 /* UNTRUSTED, probably unexploitable */
868 fprintf (fp
, segment
->text
, ctime_format (get_stat_mtime(stat_buf
)));
871 case 'u': /* user name */
873 /* (well, the actual user is selected by the user on systems
874 * where chown is not restricted, but the user name was
875 * selected by the system administrator)
880 p
= getpwuid (stat_buf
->st_uid
);
883 segment
->text
[segment
->text_len
] = 's';
884 fprintf (fp
, segment
->text
, p
->pw_name
);
890 case 'U': /* UID number */
891 /* UNTRUSTED, probably unexploitable */
892 fprintf (fp
, segment
->text
,
893 human_readable ((uintmax_t) stat_buf
->st_uid
, hbuf
,
894 human_ceiling
, 1, 1));
897 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */
898 case 'Y': /* in case of symlink */
902 if (S_ISLNK (stat_buf
->st_mode
))
905 /* If we would normally follow links, do not do so.
906 * If we would normally not follow links, do so.
908 if ((following_links() ? lstat
: stat
)
909 (state
.rel_pathname
, &sbuf
) != 0)
911 if ( errno
== ENOENT
) {
912 fprintf (fp
, segment
->text
, "N");
915 if ( errno
== ELOOP
) {
916 fprintf (fp
, segment
->text
, "L");
919 error (0, errno
, "%s", safely_quote_err_filename(0, pathname
));
923 fprintf (fp
, segment
->text
,
924 mode_to_filetype(sbuf
.st_mode
& S_IFMT
));
929 fprintf (fp
, segment
->text
,
930 mode_to_filetype(stat_buf
->st_mode
& S_IFMT
));
938 fprintf (fp
, segment
->text
,
939 mode_to_filetype(stat_buf
->st_mode
& S_IFMT
));
945 #warning this function needs a return statement. See Savannah bug#19146.
949 pred_fprintf (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
951 FILE *fp
= pred_ptr
->args
.printf_vec
.stream
;
952 struct segment
*segment
;
953 boolean ttyflag
= pred_ptr
->args
.printf_vec
.dest_is_tty
;
954 const struct quoting_options
*qopts
= pred_ptr
->args
.printf_vec
.quote_opts
;
956 for (segment
= pred_ptr
->args
.printf_vec
.segment
; segment
;
957 segment
= segment
->next
)
959 if ( (KIND_FORMAT
== segment
->segkind
) && segment
->format_char
[1]) /* Component of date. */
964 switch (segment
->format_char
[0])
967 ts
= get_stat_atime(stat_buf
);
971 ts
= get_stat_birthtime(stat_buf
);
972 if ('@' == segment
->format_char
[1])
975 valid
= (ts
.tv_nsec
>= 0);
978 ts
= get_stat_ctime(stat_buf
);
982 ts
= get_stat_mtime(stat_buf
);
989 /* We trust the output of format_date not to contain
990 * nasty characters, though the value of the date
991 * is itself untrusted data.
996 fprintf (fp
, segment
->text
,
997 format_date (ts
, segment
->format_char
[1]));
1001 /* The specified timestamp is not available, output
1002 * nothing for the timestamp, but use the rest (so that
1003 * for example find foo -printf '[%Bs] %p\n' can print
1007 fprintf (fp
, segment
->text
, "");
1012 do_fprintf(fp
, segment
, pathname
, stat_buf
, ttyflag
, qopts
);
1019 pred_fstype (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1023 if (strcmp (filesystem_type (stat_buf
, pathname
), pred_ptr
->args
.str
) == 0)
1030 pred_gid (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1034 switch (pred_ptr
->args
.numinfo
.kind
)
1037 if (stat_buf
->st_gid
> pred_ptr
->args
.numinfo
.l_val
)
1041 if (stat_buf
->st_gid
< pred_ptr
->args
.numinfo
.l_val
)
1045 if (stat_buf
->st_gid
== pred_ptr
->args
.numinfo
.l_val
)
1053 pred_group (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1057 if (pred_ptr
->args
.gid
== stat_buf
->st_gid
)
1064 pred_ilname (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1066 return match_lname (pathname
, stat_buf
, pred_ptr
, true);
1070 pred_iname (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1076 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1077 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1079 base
= base_name (pathname
);
1080 if (fnmatch (pred_ptr
->args
.str
, base
, FNM_CASEFOLD
) == 0)
1086 pred_inum (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1090 switch (pred_ptr
->args
.numinfo
.kind
)
1093 if (stat_buf
->st_ino
> pred_ptr
->args
.numinfo
.l_val
)
1097 if (stat_buf
->st_ino
< pred_ptr
->args
.numinfo
.l_val
)
1101 if (stat_buf
->st_ino
== pred_ptr
->args
.numinfo
.l_val
)
1109 pred_ipath (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1113 if (fnmatch (pred_ptr
->args
.str
, pathname
, FNM_CASEFOLD
) == 0)
1119 pred_links (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1123 switch (pred_ptr
->args
.numinfo
.kind
)
1126 if (stat_buf
->st_nlink
> pred_ptr
->args
.numinfo
.l_val
)
1130 if (stat_buf
->st_nlink
< pred_ptr
->args
.numinfo
.l_val
)
1134 if (stat_buf
->st_nlink
== pred_ptr
->args
.numinfo
.l_val
)
1142 pred_lname (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1144 return match_lname (pathname
, stat_buf
, pred_ptr
, false);
1148 match_lname (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
, boolean ignore_case
)
1150 boolean ret
= false;
1152 if (S_ISLNK (stat_buf
->st_mode
))
1154 char *linkname
= get_link_name_at (pathname
, state
.cwd_dir_fd
, state
.rel_pathname
);
1157 if (fnmatch (pred_ptr
->args
.str
, linkname
,
1158 ignore_case
? FNM_CASEFOLD
: 0) == 0)
1163 #endif /* S_ISLNK */
1168 pred_ls (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1170 list_file (pathname
, state
.cwd_dir_fd
, state
.rel_pathname
,
1171 stat_buf
, options
.start_time
.tv_sec
,
1172 options
.output_block_size
,
1173 pred_ptr
->literal_control_chars
,
1179 pred_mmin (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1182 return pred_timewindow(get_stat_mtime(stat_buf
), pred_ptr
, 60);
1186 pred_mtime (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1189 return pred_timewindow(get_stat_mtime(stat_buf
), pred_ptr
, DAYSECS
);
1193 pred_name (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1198 base
= base_name (pathname
);
1200 /* FNM_PERIOD is not used here because POSIX requires that it not be.
1201 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html
1203 if (fnmatch (pred_ptr
->args
.str
, base
, 0) == 0)
1209 pred_negate (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1211 return !apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_right
);
1215 pred_newer (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1219 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
1220 return compare_ts(get_stat_mtime(stat_buf
), pred_ptr
->args
.reftime
.ts
) > 0;
1224 pred_newerXY (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1227 boolean collected
= false;
1229 assert(COMP_GT
== pred_ptr
->args
.reftime
.kind
);
1231 switch (pred_ptr
->args
.reftime
.xval
)
1234 assert(pred_ptr
->args
.reftime
.xval
!= XVAL_TIME
);
1238 ts
= get_stat_atime(stat_buf
);
1242 case XVAL_BIRTHTIME
:
1243 ts
= get_stat_birthtime(stat_buf
);
1245 if (ts
.tv_nsec
< 0);
1247 /* XXX: Cannot determine birth time. Warn once. */
1248 error(0, 0, _("Warning: cannot determine birth time of file %s"),
1249 safely_quote_err_filename(0, pathname
));
1255 ts
= get_stat_ctime(stat_buf
);
1260 ts
= get_stat_mtime(stat_buf
);
1266 return compare_ts(ts
, pred_ptr
->args
.reftime
.ts
) > 0;
1270 pred_nogroup (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1276 extern char *gid_unused
;
1278 return gid_unused
[(unsigned) stat_buf
->st_gid
];
1280 return getgrgid (stat_buf
->st_gid
) == NULL
;
1285 pred_nouser (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1288 extern char *uid_unused
;
1295 return uid_unused
[(unsigned) stat_buf
->st_uid
];
1297 return getpwuid (stat_buf
->st_uid
) == NULL
;
1303 is_ok(const char *program
, const char *arg
)
1306 /* The draft open standard requires that, in the POSIX locale,
1307 the last non-blank character of this prompt be '?'.
1308 The exact format is not specified.
1309 This standard does not have requirements for locales other than POSIX
1311 /* XXX: printing UNTRUSTED data here. */
1312 fprintf (stderr
, _("< %s ... %s > ? "), program
, arg
);
1318 pred_ok (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1320 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1321 return new_impl_pred_exec (get_start_dirfd(),
1322 pathname
, stat_buf
, pred_ptr
, NULL
, 0);
1328 pred_okdir (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1330 const char *prefix
= (state
.rel_pathname
[0] == '/') ? NULL
: "./";
1331 if (is_ok(pred_ptr
->args
.exec_vec
.replace_vec
[0], pathname
))
1332 return new_impl_pred_exec (get_current_dirfd(),
1333 state
.rel_pathname
, stat_buf
, pred_ptr
,
1334 prefix
, (prefix
? 2 : 0));
1340 pred_openparen (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1349 pred_or (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1351 if (pred_ptr
->pred_left
== NULL
1352 || !apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_left
))
1354 return apply_predicate(pathname
, stat_buf
, pred_ptr
->pred_right
);
1361 pred_path (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1364 if (fnmatch (pred_ptr
->args
.str
, pathname
, 0) == 0)
1370 pred_perm (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1372 mode_t mode
= stat_buf
->st_mode
;
1373 mode_t perm_val
= pred_ptr
->args
.perm
.val
[S_ISDIR (mode
) != 0];
1375 switch (pred_ptr
->args
.perm
.kind
)
1378 return (mode
& perm_val
) == perm_val
;
1382 /* True if any of the bits set in the mask are also set in the file's mode.
1385 * Otherwise, if onum is prefixed by a hyphen, the primary shall
1386 * evaluate as true if at least all of the bits specified in
1387 * onum that are also set in the octal mask 07777 are set.
1389 * Eric Blake's interpretation is that the mode argument is zero,
1393 return true; /* Savannah bug 14748; we used to return false */
1395 return (mode
& perm_val
) != 0;
1399 return (mode
& MODE_ALL
) == perm_val
;
1409 struct access_check_args
1411 const char *filename
;
1418 access_callback(void *context
)
1421 struct access_check_args
*args
= context
;
1422 if ((rv
= access(args
->filename
, args
->access_type
)) < 0)
1423 args
->cb_errno
= errno
;
1428 can_access(int access_type
)
1430 struct access_check_args args
;
1431 args
.filename
= state
.rel_pathname
;
1432 args
.access_type
= access_type
;
1434 return 0 == run_in_dir(state
.cwd_dir_fd
, access_callback
, &args
);
1439 pred_executable (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1445 return can_access(X_OK
);
1449 pred_readable (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1455 return can_access(R_OK
);
1459 pred_writable (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1465 return can_access(W_OK
);
1469 pred_print (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1473 /* puts (pathname); */
1474 print_quoted(pred_ptr
->args
.printf_vec
.stream
,
1475 pred_ptr
->args
.printf_vec
.quote_opts
,
1476 pred_ptr
->args
.printf_vec
.dest_is_tty
,
1482 pred_print0 (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1486 fputs (pathname
, stdout
);
1492 pred_prune (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1497 if (options
.do_dir_first
== true &&
1499 S_ISDIR(stat_buf
->st_mode
))
1500 state
.stop_at_current_level
= true;
1502 return (options
.do_dir_first
); /* This is what SunOS find seems to do. */
1506 pred_quit (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1512 /* Run any cleanups. This includes executing any command lines
1513 * we have partly built but not executed.
1517 /* Since -exec and friends don't leave child processes running in the
1518 * background, there is no need to wait for them here.
1520 exit(state
.exit_status
); /* 0 for success, etc. */
1524 pred_regex (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1526 int len
= strlen (pathname
);
1528 if (re_match (pred_ptr
->args
.regex
, pathname
, len
, 0,
1529 (struct re_registers
*) NULL
) == len
)
1535 pred_size (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1540 f_val
= ((stat_buf
->st_size
/ pred_ptr
->args
.size
.blocksize
)
1541 + (stat_buf
->st_size
% pred_ptr
->args
.size
.blocksize
!= 0));
1542 switch (pred_ptr
->args
.size
.kind
)
1545 if (f_val
> pred_ptr
->args
.size
.size
)
1549 if (f_val
< pred_ptr
->args
.size
.size
)
1553 if (f_val
== pred_ptr
->args
.size
.size
)
1561 pred_samefile (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1563 /* Potential optimisation: because of the loop protection, we always
1564 * know the device of the current directory, hence the device number
1565 * of the file we're currently considering. If -L is not in effect,
1566 * and the device number of the file we're looking for is not the
1567 * same as the device number of the current directory, this
1568 * predicate cannot return true. Hence there would be no need to
1569 * stat the file we're looking at.
1573 /* We will often still have an fd open on the file under consideration,
1574 * but that's just to ensure inode number stability by maintaining
1575 * a reference to it; we don't need the file for anything else.
1577 return stat_buf
->st_ino
== pred_ptr
->args
.samefileid
.ino
1578 && stat_buf
->st_dev
== pred_ptr
->args
.samefileid
.dev
;
1582 pred_true (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1591 pred_type (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1594 mode_t type
= pred_ptr
->args
.type
;
1596 assert(state
.have_type
);
1598 if (0 == state
.type
)
1600 /* This can sometimes happen with broken NFS servers.
1601 * See Savannah bug #16378.
1608 if (state
.have_stat
)
1609 mode
= stat_buf
->st_mode
;
1614 /* POSIX system; check `mode' the slow way. */
1615 if ((S_ISBLK (mode
) && type
== S_IFBLK
)
1616 || (S_ISCHR (mode
) && type
== S_IFCHR
)
1617 || (S_ISDIR (mode
) && type
== S_IFDIR
)
1618 || (S_ISREG (mode
) && type
== S_IFREG
)
1620 || (S_ISLNK (mode
) && type
== S_IFLNK
)
1623 || (S_ISFIFO (mode
) && type
== S_IFIFO
)
1626 || (S_ISSOCK (mode
) && type
== S_IFSOCK
)
1629 || (S_ISDOOR (mode
) && type
== S_IFDOOR
)
1633 /* Unix system; check `mode' the fast way. */
1634 if ((mode
& S_IFMT
) == type
)
1642 pred_uid (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1645 switch (pred_ptr
->args
.numinfo
.kind
)
1648 if (stat_buf
->st_uid
> pred_ptr
->args
.numinfo
.l_val
)
1652 if (stat_buf
->st_uid
< pred_ptr
->args
.numinfo
.l_val
)
1656 if (stat_buf
->st_uid
== pred_ptr
->args
.numinfo
.l_val
)
1664 pred_used (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1666 struct timespec delta
, at
, ct
;
1670 /* TODO: this needs to be retested carefully (manually, if necessary) */
1671 at
= get_stat_atime(stat_buf
);
1672 ct
= get_stat_ctime(stat_buf
);
1673 delta
.tv_sec
= at
.tv_sec
- ct
.tv_sec
;
1674 delta
.tv_nsec
= at
.tv_nsec
- ct
.tv_nsec
;
1675 if (delta
.tv_nsec
< 0)
1677 delta
.tv_nsec
+= 1000000000;
1680 return pred_timewindow(delta
, pred_ptr
, DAYSECS
);
1684 pred_user (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1687 if (pred_ptr
->args
.uid
== stat_buf
->st_uid
)
1694 pred_xtype (const char *pathname
, struct stat
*stat_buf
, struct predicate
*pred_ptr
)
1696 struct stat sbuf
; /* local copy, not stat_buf because we're using a different stat method */
1697 int (*ystat
) (const char*, struct stat
*p
);
1699 /* If we would normally stat the link itself, stat the target instead.
1700 * If we would normally follow the link, stat the link itself instead.
1702 if (following_links())
1703 ystat
= optionp_stat
;
1705 ystat
= optionl_stat
;
1707 set_stat_placeholders(&sbuf
);
1708 if ((*ystat
) (state
.rel_pathname
, &sbuf
) != 0)
1710 if (following_links() && errno
== ENOENT
)
1712 /* If we failed to follow the symlink,
1713 * fall back on looking at the symlink itself.
1715 /* Mimic behavior of ls -lL. */
1716 return (pred_type (pathname
, stat_buf
, pred_ptr
));
1720 error (0, errno
, "%s", safely_quote_err_filename(0, pathname
));
1721 state
.exit_status
= 1;
1725 /* Now that we have our stat() information, query it in the same
1726 * way that -type does.
1728 return (pred_type (pathname
, &sbuf
, pred_ptr
));
1731 /* 1) fork to get a child; parent remembers the child pid
1732 2) child execs the command requested
1733 3) parent waits for child; checks for proper pid of child
1737 ret errno status(h) status(l)
1739 pid x signal# 0177 stopped
1740 pid x exit arg 0 term by _exit
1741 pid x 0 signal # term by signal
1742 -1 EINTR parent got signal
1743 -1 other some other kind of error
1745 Return true only if the pid matches, status(l) is
1746 zero, and the exit arg (status high) is 0.
1747 Otherwise return false, possibly printing an error message. */
1751 prep_child_for_exec (boolean close_stdin
, int dirfd
)
1756 const char inputfile
[] = "/dev/null";
1760 error(0, errno
, _("Cannot close standard input"));
1765 if (open(inputfile
, O_RDONLY
1766 #if defined O_LARGEFILE
1771 /* This is not entirely fatal, since
1772 * executing the child with a closed
1773 * stdin is almost as good as executing it
1774 * with its stdin attached to /dev/null.
1776 error (0, errno
, "%s", safely_quote_err_filename(0, inputfile
));
1777 /* do not set ok=false, it is OK to continue anyway. */
1782 /* Even if DebugSearch is set, don't announce our change of
1783 * directory, since we're not going to emit a subsequent
1784 * announcement of a call to stat() anyway, as we're about to exec
1787 if (dirfd
!= AT_FDCWD
)
1790 if (0 != fchdir(dirfd
))
1792 /* If we cannot execute our command in the correct directory,
1793 * we should not execute it at all.
1795 error(0, errno
, _("Failed to change directory"));
1805 launch (const struct buildcmd_control
*ctl
,
1806 struct buildcmd_state
*buildstate
)
1810 static int first_time
= 1;
1811 const struct exec_val
*execp
= buildstate
->usercontext
;
1813 if (!execp
->use_current_dir
)
1815 assert(starting_desc
>= 0);
1816 assert(execp
->dirfd
== starting_desc
);
1820 /* Null terminate the arg list. */
1821 bc_push_arg (ctl
, buildstate
, (char *) NULL
, 0, NULL
, 0, false);
1823 /* Make sure output of command doesn't get mixed with find output. */
1827 /* Make sure to listen for the kids. */
1831 signal (SIGCHLD
, SIG_DFL
);
1834 child_pid
= fork ();
1835 if (child_pid
== -1)
1836 error (1, errno
, _("cannot fork"));
1839 /* We are the child. */
1840 assert(starting_desc
>= 0);
1841 if (!prep_child_for_exec(execp
->close_stdin
, execp
->dirfd
))
1846 execvp (buildstate
->cmd_argv
[0], buildstate
->cmd_argv
);
1847 error (0, errno
, "%s",
1848 safely_quote_err_filename(0, buildstate
->cmd_argv
[0]));
1853 /* In parent; set up for next time. */
1854 bc_clear_args(ctl
, buildstate
);
1857 while (waitpid (child_pid
, &wait_status
, 0) == (pid_t
) -1)
1861 error (0, errno
, _("error waiting for %s"),
1862 safely_quote_err_filename(0, buildstate
->cmd_argv
[0]));
1863 state
.exit_status
= 1;
1864 return 0; /* FAIL */
1868 if (WIFSIGNALED (wait_status
))
1870 error (0, 0, _("%s terminated by signal %d"),
1871 quotearg_n_style(0, options
.err_quoting_style
,
1872 buildstate
->cmd_argv
[0]),
1873 WTERMSIG (wait_status
));
1875 if (execp
->multiple
)
1877 /* -exec \; just returns false if the invoked command fails.
1878 * -exec {} + returns true if the invoked command fails, but
1879 * sets the program exit status.
1881 state
.exit_status
= 1;
1887 if (0 == WEXITSTATUS (wait_status
))
1893 if (execp
->multiple
)
1895 /* -exec \; just returns false if the invoked command fails.
1896 * -exec {} + returns true if the invoked command fails, but
1897 * sets the program exit status.
1899 state
.exit_status
= 1;
1901 return 0; /* FAIL */
1907 /* Return a static string formatting the time WHEN according to the
1908 * strftime format character KIND.
1910 * This function contains a number of assertions. These look like
1911 * runtime checks of the results of computations, which would be a
1912 * problem since external events should not be tested for with
1913 * "assert" (instead you should use "if"). However, they are not
1914 * really runtime checks. The assertions actually exist to verify
1915 * that the various buffers are correctly sized.
1918 format_date (struct timespec ts
, int kind
)
1920 /* In theory, we use an extra 10 characters for 9 digits of
1921 * nanoseconds and 1 for the decimal point. However, the real
1922 * world is more complex than that.
1924 * For example, some systems return junk in the tv_nsec part of
1925 * st_birthtime. An example of this is the NetBSD-4.0-RELENG kernel
1926 * (at Sat Mar 24 18:46:46 2007) running a NetBSD-3.1-RELEASE
1927 * runtime and examining files on an msdos filesytem. So for that
1928 * reason we set NS_BUF_LEN to 32, which is simply "long enough" as
1929 * opposed to "exactly the right size". Note that the behaviour of
1930 * NetBSD appears to be a result of the use of uninitialised data,
1931 * as it's not 100% reproducible (more like 25%).
1935 DATE_LEN_PERCENT_APLUS
=21 /* length of result of %A+ (it's longer than %c)*/
1937 static char buf
[128u+10u + MAX(DATE_LEN_PERCENT_APLUS
,
1938 MAX (LONGEST_HUMAN_READABLE
+ 2, NS_BUF_LEN
+64+200))];
1939 char ns_buf
[NS_BUF_LEN
]; /* -.9999999990 (- sign can happen!)*/
1940 int charsprinted
, need_ns_suffix
;
1944 /* human_readable() assumes we pass a buffer which is at least as
1945 * long as LONGEST_HUMAN_READABLE. We use an assertion here to
1946 * ensure that no nasty unsigned overflow happend in our calculation
1947 * of the size of buf. Do the assertion here rather than in the
1948 * code for %@ so that we find the problem quickly if it exists. If
1949 * you want to submit a patch to move this into the if statement, go
1950 * ahead, I'll apply it. But include performance timings
1951 * demonstrating that the performance difference is actually
1954 assert(sizeof(buf
) >= LONGEST_HUMAN_READABLE
);
1959 /* Format the main part of the time. */
1962 strcpy (fmt
, "%F+%T");
1971 /* %a, %c, and %t are handled in ctime_format() */
1988 /* Format the nanoseconds part. Leave a trailing zero to
1989 * discourage people from writing scripts which extract the
1990 * fractional part of the timestamp by using column offsets.
1991 * The reason for discouraging this is that in the future, the
1992 * granularity may not be nanoseconds.
1995 charsprinted
= snprintf(ns_buf
, NS_BUF_LEN
, ".%09ld0", (long int)ts
.tv_nsec
);
1996 assert(charsprinted
< NS_BUF_LEN
);
2000 && (tm
= localtime (&ts
.tv_sec
))
2001 && strftime (buf
, sizeof buf
, fmt
, tm
))
2003 /* For %AS, %CS, %TS, add the fractional part of the seconds
2008 assert((sizeof buf
- strlen(buf
)) > strlen(ns_buf
));
2009 strcat(buf
, ns_buf
);
2015 uintmax_t w
= ts
.tv_sec
;
2016 size_t used
, len
, remaining
;
2018 /* XXX: note that we are negating an unsigned type which is the
2019 * widest possible unsigned type.
2021 char *p
= human_readable (ts
.tv_sec
< 0 ? -w
: w
, buf
+ 1,
2022 human_ceiling
, 1, 1);
2024 assert(p
< (buf
+ (sizeof buf
)));
2026 *--p
= '-'; /* XXX: Ugh, relying on internal details of human_readable(). */
2028 /* Add the nanoseconds part. Because we cannot enforce a
2029 * particlar implementation of human_readable, we cannot assume
2030 * any particular value for (p-buf). So we need to be careful
2031 * that there is enough space remaining in the buffer.
2036 used
= (p
-buf
) + len
; /* Offset into buf of current end */
2037 assert(sizeof buf
> used
); /* Ensure we can perform subtraction safely. */
2038 remaining
= sizeof buf
- used
- 1u; /* allow space for NUL */
2040 if (strlen(ns_buf
) >= remaining
)
2043 "charsprinted=%ld but remaining=%lu: ns_buf=%s",
2044 (long)charsprinted
, (unsigned long)remaining
, ns_buf
);
2046 assert(strlen(ns_buf
) < remaining
);
2053 static const char *weekdays
[] =
2055 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
2057 static char * months
[] =
2059 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
2060 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
2065 ctime_format (struct timespec ts
)
2067 const struct tm
* ptm
;
2068 #define TIME_BUF_LEN 1024u
2069 static char resultbuf
[TIME_BUF_LEN
];
2072 ptm
= localtime(&ts
.tv_sec
);
2075 assert(ptm
->tm_wday
>= 0);
2076 assert(ptm
->tm_wday
< 7);
2077 assert(ptm
->tm_mon
>= 0);
2078 assert(ptm
->tm_mon
< 12);
2079 assert(ptm
->tm_hour
>= 0);
2080 assert(ptm
->tm_hour
< 24);
2081 assert(ptm
->tm_min
< 60);
2082 assert(ptm
->tm_sec
<= 61); /* allows 2 leap seconds. */
2084 /* wkday mon mday hh:mm:ss.nnnnnnnnn yyyy */
2085 nout
= snprintf(resultbuf
, TIME_BUF_LEN
,
2086 "%3s %3s %2d %02d:%02d:%02d.%010ld %04d",
2087 weekdays
[ptm
->tm_wday
],
2088 months
[ptm
->tm_mon
],
2093 (long int)ts
.tv_nsec
,
2094 1900 + ptm
->tm_year
);
2096 assert(nout
< TIME_BUF_LEN
);
2101 /* The time cannot be represented as a struct tm.
2102 Output it as an integer. */
2103 return format_date (ts
, '@');
2107 /* Copy STR into BUF and trim blanks from the end of BUF.
2111 blank_rtrim (str
, buf
)
2120 i
= strlen (buf
) - 1;
2121 while ((i
>= 0) && ((buf
[i
] == ' ') || buf
[i
] == '\t'))
2127 /* Print out the predicate list starting at NODE. */
2129 print_list (FILE *fp
, struct predicate
*node
)
2131 struct predicate
*cur
;
2137 fprintf (fp
, "%s ", blank_rtrim (cur
->p_name
, name
));
2138 cur
= cur
->pred_next
;
2143 /* Print out the predicate list starting at NODE. */
2145 print_parenthesised(FILE *fp
, struct predicate
*node
)
2151 if ((pred_is(node
, pred_or
) || pred_is(node
, pred_and
))
2152 && node
->pred_left
== NULL
)
2154 /* We print "<nothing> or X" as just "X"
2155 * We print "<nothing> and X" as just "X"
2157 print_parenthesised(fp
, node
->pred_right
);
2161 if (node
->pred_left
|| node
->pred_right
)
2165 fprintf(fp
, "%s", " ( ");
2166 print_optlist(fp
, node
);
2168 fprintf(fp
, "%s", " ) ");
2174 print_optlist (FILE *fp
, const struct predicate
*p
)
2178 print_parenthesised(fp
, p
->pred_left
);
2181 p
->need_stat
? "[call stat] " : "",
2182 p
->need_type
? "[need type] " : "");
2183 print_predicate(fp
, p
);
2184 fprintf(fp
, " [%g] ", p
->est_success_rate
);
2185 if (options
.debug_options
& DebugSuccessRates
)
2187 fprintf(fp
, "[%ld/%ld", p
->perf
.successes
, p
->perf
.visits
);
2190 double real_rate
= (double)p
->perf
.successes
/ (double)p
->perf
.visits
;
2191 fprintf(fp
, "=%g] ", real_rate
);
2195 fprintf(fp
, "=_] ");
2198 print_parenthesised(fp
, p
->pred_right
);
2202 void show_success_rates(const struct predicate
*p
)
2204 if (options
.debug_options
& DebugSuccessRates
)
2206 fprintf(stderr
, "Predicate success rates after completion:\n");
2207 print_optlist(stderr
, p
);
2208 fprintf(stderr
, "\n");
2216 /* If _NDEBUG is defined, the assertions will do nothing. Hence
2217 * there is no point in having a function body for pred_sanity_check()
2218 * if that preprocessor macro is defined.
2221 pred_sanity_check(const struct predicate
*predicates
)
2223 /* Do nothing, since assert() is a no-op with _NDEBUG set */
2228 pred_sanity_check(const struct predicate
*predicates
)
2230 const struct predicate
*p
;
2232 for (p
=predicates
; p
!= NULL
; p
=p
->pred_next
)
2234 /* All predicates must do something. */
2235 assert(p
->pred_func
!= NULL
);
2237 /* All predicates must have a parser table entry. */
2238 assert(p
->parser_entry
!= NULL
);
2240 /* If the parser table tells us that just one predicate function is
2241 * possible, verify that that is still the one that is in effect.
2242 * If the parser has NULL for the predicate function, that means that
2243 * the parse_xxx function fills it in, so we can't check it.
2245 if (p
->parser_entry
->pred_func
)
2247 assert(p
->parser_entry
->pred_func
== p
->pred_func
);
2250 switch (p
->parser_entry
->type
)
2252 /* Options all take effect during parsing, so there should
2253 * be no predicate entries corresponding to them. Hence we
2254 * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION
2257 * This is a silly way of coding this test, but it prevents
2258 * a compiler warning (i.e. otherwise it would think that
2259 * there would be case statements missing).
2262 case ARG_POSITIONAL_OPTION
:
2263 assert(p
->parser_entry
->type
!= ARG_OPTION
);
2264 assert(p
->parser_entry
->type
!= ARG_POSITIONAL_OPTION
);
2268 assert(p
->side_effects
); /* actions have side effects. */
2269 if (!pred_is(p
, pred_prune
) && !pred_is(p
, pred_quit
))
2271 /* actions other than -prune and -quit should
2272 * inhibit the default -print
2274 assert(p
->no_default_print
);
2278 /* We happen to know that the only user of ARG_SPECIAL_PARSE
2279 * is a test, so handle it like ARG_TEST.
2281 case ARG_SPECIAL_PARSE
:
2283 case ARG_PUNCTUATION
:
2285 /* Punctuation and tests should have no side
2286 * effects and not inhibit default print.
2288 assert(!p
->no_default_print
);
2289 assert(!p
->side_effects
);