1/* pred.c -- execute the expression tree. 2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003, 3 2004, 2005, 2007 Free Software Foundation, Inc. 4 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 3 of the License, or 8 (at your option) any later version. 9 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. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17*/ 18 19#include "defs.h" 20 21#include <fnmatch.h> 22#include <signal.h> 23#include <pwd.h> 24#include <grp.h> 25#include <sys/types.h> 26#include <sys/stat.h> 27#include <assert.h> 28#include <fcntl.h> 29#include "xalloc.h" 30#include "dirname.h" 31#include "human.h" 32#include "modetype.h" 33#include "filemode.h" 34#include "wait.h" 35#include "printquoted.h" 36#include "buildcmd.h" 37#include "yesno.h" 38 39#if ENABLE_NLS 40# include <libintl.h> 41# define _(Text) gettext (Text) 42#else 43# define _(Text) Text 44#endif 45#ifdef gettext_noop 46# define N_(String) gettext_noop (String) 47#else 48/* See locate.c for explanation as to why not use (String) */ 49# define N_(String) String 50#endif 51 52#if !defined(SIGCHLD) && defined(SIGCLD) 53#define SIGCHLD SIGCLD 54#endif 55 56 57 58#if HAVE_DIRENT_H 59# include <dirent.h> 60# define NAMLEN(dirent) strlen((dirent)->d_name) 61#else 62# define dirent direct 63# define NAMLEN(dirent) (dirent)->d_namlen 64# if HAVE_SYS_NDIR_H 65# include <sys/ndir.h> 66# endif 67# if HAVE_SYS_DIR_H 68# include <sys/dir.h> 69# endif 70# if HAVE_NDIR_H 71# include <ndir.h> 72# endif 73#endif 74 75#ifdef CLOSEDIR_VOID 76/* Fake a return value. */ 77#define CLOSEDIR(d) (closedir (d), 0) 78#else 79#define CLOSEDIR(d) closedir (d) 80#endif 81 82 83 84 85/* Get or fake the disk device blocksize. 86 Usually defined by sys/param.h (if at all). */ 87#ifndef DEV_BSIZE 88# ifdef BSIZE 89# define DEV_BSIZE BSIZE 90# else /* !BSIZE */ 91# define DEV_BSIZE 4096 92# endif /* !BSIZE */ 93#endif /* !DEV_BSIZE */ 94 95/* Extract or fake data from a `struct stat'. 96 ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes. 97 ST_NBLOCKS: Number of blocks in the file, including indirect blocks. 98 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */ 99#ifndef HAVE_STRUCT_STAT_ST_BLOCKS 100# define ST_BLKSIZE(statbuf) DEV_BSIZE 101# if defined(_POSIX_SOURCE) || !defined(BSIZE) /* fileblocks.c uses BSIZE. */ 102# define ST_NBLOCKS(statbuf) \ 103 (S_ISREG ((statbuf).st_mode) \ 104 || S_ISDIR ((statbuf).st_mode) \ 105 ? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0) 106# else /* !_POSIX_SOURCE && BSIZE */ 107# define ST_NBLOCKS(statbuf) \ 108 (S_ISREG ((statbuf).st_mode) \ 109 || S_ISDIR ((statbuf).st_mode) \ 110 ? st_blocks ((statbuf).st_size) : 0) 111# endif /* !_POSIX_SOURCE && BSIZE */ 112#else /* HAVE_STRUCT_STAT_ST_BLOCKS */ 113/* Some systems, like Sequents, return st_blksize of 0 on pipes. */ 114# define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \ 115 ? (statbuf).st_blksize : DEV_BSIZE) 116# if defined(hpux) || defined(__hpux__) || defined(__hpux) 117/* HP-UX counts st_blocks in 1024-byte units. 118 This loses when mixing HP-UX and BSD filesystems with NFS. */ 119# define ST_NBLOCKSIZE 1024 120# else /* !hpux */ 121# if defined(_AIX) && defined(_I386) 122/* AIX PS/2 counts st_blocks in 4K units. */ 123# define ST_NBLOCKSIZE (4 * 1024) 124# else /* not AIX PS/2 */ 125# if defined(_CRAY) 126# define ST_NBLOCKS(statbuf) \ 127 (S_ISREG ((statbuf).st_mode) \ 128 || S_ISDIR ((statbuf).st_mode) \ 129 ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0) 130# endif /* _CRAY */ 131# endif /* not AIX PS/2 */ 132# endif /* !hpux */ 133#endif /* HAVE_STRUCT_STAT_ST_BLOCKS */ 134 135#ifndef ST_NBLOCKS 136# define ST_NBLOCKS(statbuf) \ 137 (S_ISREG ((statbuf).st_mode) \ 138 || S_ISDIR ((statbuf).st_mode) \ 139 ? (statbuf).st_blocks : 0) 140#endif 141 142#ifndef ST_NBLOCKSIZE 143# define ST_NBLOCKSIZE 512 144#endif 145 146 147#undef MAX 148#define MAX(a, b) ((a) > (b) ? (a) : (b)) 149 150static boolean insert_lname PARAMS((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case)); 151 152static char *format_date PARAMS((time_t when, int kind)); 153static char *ctime_format PARAMS((time_t when)); 154 155#ifdef DEBUG 156typedef boolean (*PFB) (char *, struct stat *, struct predicate *); 157 158struct pred_assoc 159{ 160 PFB pred_func; 161 char *pred_name; 162}; 163 164struct pred_assoc pred_table[] = 165{ 166 {pred_amin, "amin "}, 167 {pred_and, "and "}, 168 {pred_anewer, "anewer "}, 169 {pred_atime, "atime "}, 170 {pred_closeparen, ") "}, 171 {pred_amin, "cmin "}, 172 {pred_cnewer, "cnewer "}, 173 {pred_comma, ", "}, 174 {pred_ctime, "ctime "}, 175 {pred_delete, "delete "}, 176 {pred_empty, "empty "}, 177 {pred_exec, "exec "}, 178 {pred_execdir, "execdir "}, 179 {pred_false, "false "}, 180 {pred_fprint, "fprint "}, 181 {pred_fprint0, "fprint0 "}, 182 {pred_fprintf, "fprintf "}, 183 {pred_fstype, "fstype "}, 184 {pred_gid, "gid "}, 185 {pred_group, "group "}, 186 {pred_ilname, "ilname "}, 187 {pred_iname, "iname "}, 188 {pred_inum, "inum "}, 189 {pred_ipath, "ipath "}, 190 {pred_links, "links "}, 191 {pred_lname, "lname "}, 192 {pred_ls, "ls "}, 193 {pred_amin, "mmin "}, 194 {pred_mtime, "mtime "}, 195 {pred_name, "name "}, 196 {pred_negate, "not "}, 197 {pred_newer, "newer "}, 198 {pred_nogroup, "nogroup "}, 199 {pred_nouser, "nouser "}, 200 {pred_ok, "ok "}, 201 {pred_okdir, "okdir "}, 202 {pred_openparen, "( "}, 203 {pred_or, "or "}, 204 {pred_path, "path "}, 205 {pred_perm, "perm "}, 206 {pred_print, "print "}, 207 {pred_print0, "print0 "}, 208 {pred_prune, "prune "}, 209 {pred_regex, "regex "}, 210 {pred_samefile,"samefile "}, 211 {pred_size, "size "}, 212 {pred_true, "true "}, 213 {pred_type, "type "}, 214 {pred_uid, "uid "}, 215 {pred_used, "used "}, 216 {pred_user, "user "}, 217 {pred_xtype, "xtype "}, 218 {0, "none "} 219}; 220 221struct op_assoc 222{ 223 short type; 224 char *type_name; 225}; 226 227struct op_assoc type_table[] = 228{ 229 {NO_TYPE, "no "}, 230 {PRIMARY_TYPE, "primary "}, 231 {UNI_OP, "uni_op "}, 232 {BI_OP, "bi_op "}, 233 {OPEN_PAREN, "open_paren "}, 234 {CLOSE_PAREN, "close_paren "}, 235 {-1, "unknown "} 236}; 237 238struct prec_assoc 239{ 240 short prec; 241 char *prec_name; 242}; 243 244struct prec_assoc prec_table[] = 245{ 246 {NO_PREC, "no "}, 247 {COMMA_PREC, "comma "}, 248 {OR_PREC, "or "}, 249 {AND_PREC, "and "}, 250 {NEGATE_PREC, "negate "}, 251 {MAX_PREC, "max "}, 252 {-1, "unknown "} 253}; 254#endif /* DEBUG */ 255 256/* Predicate processing routines. 257 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. 261 262 Return true if the file passes this predicate, false if not. */ 263 264 265/* pred_timewindow 266 * 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. 271 */ 272static boolean 273pred_timewindow(time_t the_time, struct predicate const *pred_ptr, int window) 274{ 275 switch (pred_ptr->args.info.kind) 276 { 277 case COMP_GT: 278 if (the_time > (time_t) pred_ptr->args.info.l_val) 279 return true; 280 break; 281 case COMP_LT: 282 if (the_time < (time_t) pred_ptr->args.info.l_val) 283 return true; 284 break; 285 case COMP_EQ: 286 if ((the_time >= (time_t) pred_ptr->args.info.l_val) 287 && (the_time < (time_t) pred_ptr->args.info.l_val + window)) 288 return true; 289 break; 290 } 291 return false; 292} 293 294 295boolean 296pred_amin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 297{ 298 (void) &pathname; 299 return pred_timewindow(stat_buf->st_atime, pred_ptr, 60); 300} 301 302boolean 303pred_and (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 304{ 305 if (pred_ptr->pred_left == NULL 306 || (*pred_ptr->pred_left->pred_func) (pathname, stat_buf, 307 pred_ptr->pred_left)) 308 { 309 /* Check whether we need a stat here. */ 310 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0) 311 return false; 312 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf, 313 pred_ptr->pred_right)); 314 } 315 else 316 return (false); 317} 318 319boolean 320pred_anewer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 321{ 322 (void) &pathname; 323 324 if (stat_buf->st_atime > pred_ptr->args.time) 325 return (true); 326 return (false); 327} 328 329boolean 330pred_atime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 331{ 332 (void) &pathname; 333 return pred_timewindow(stat_buf->st_atime, pred_ptr, DAYSECS); 334} 335 336boolean 337pred_closeparen (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 338{ 339 (void) &pathname; 340 (void) &stat_buf; 341 (void) &pred_ptr; 342 343 return true; 344} 345 346boolean 347pred_cmin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 348{ 349 (void) pathname; 350 return pred_timewindow(stat_buf->st_ctime, pred_ptr, 60); 351} 352 353boolean 354pred_cnewer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 355{ 356 (void) pathname; 357 358 if (stat_buf->st_ctime > pred_ptr->args.time) 359 return true; 360 else 361 return false; 362} 363 364boolean 365pred_comma (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 366{ 367 if (pred_ptr->pred_left != NULL) 368 (*pred_ptr->pred_left->pred_func) (pathname, stat_buf, 369 pred_ptr->pred_left); 370 /* Check whether we need a stat here. */ 371 /* TODO: what about need_type? */ 372 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0) 373 return false; 374 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf, 375 pred_ptr->pred_right)); 376} 377 378boolean 379pred_ctime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 380{ 381 (void) &pathname; 382 return pred_timewindow(stat_buf->st_ctime, pred_ptr, DAYSECS); 383} 384 385boolean 386pred_delete (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 387{ 388 (void) pred_ptr; 389 (void) stat_buf; 390 if (strcmp (state.rel_pathname, ".")) 391 { 392 if (0 != remove (state.rel_pathname)) 393 { 394 error (0, errno, "cannot delete %s", pathname); 395 return false; 396 } 397 else 398 { 399 return true; 400 } 401 } 402 403 /* nothing to do. */ 404 return true; 405} 406 407boolean 408pred_empty (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 409{ 410 (void) pathname; 411 (void) pred_ptr; 412 413 if (S_ISDIR (stat_buf->st_mode)) 414 { 415 DIR *d; 416 struct dirent *dp; 417 boolean empty = true; 418 419 errno = 0; 420 d = opendir (state.rel_pathname); 421 if (d == NULL) 422 { 423 error (0, errno, "%s", pathname); 424 state.exit_status = 1; 425 return false; 426 } 427 for (dp = readdir (d); dp; dp = readdir (d)) 428 { 429 if (dp->d_name[0] != '.' 430 || (dp->d_name[1] != '\0' 431 && (dp->d_name[1] != '.' || dp->d_name[2] != '\0'))) 432 { 433 empty = false; 434 break; 435 } 436 } 437 if (CLOSEDIR (d)) 438 { 439 error (0, errno, "%s", pathname); 440 state.exit_status = 1; 441 return false; 442 } 443 return (empty); 444 } 445 else if (S_ISREG (stat_buf->st_mode)) 446 return (stat_buf->st_size == 0); 447 else 448 return (false); 449} 450 451static boolean 452new_impl_pred_exec (const char *pathname, struct stat *stat_buf, 453 struct predicate *pred_ptr, 454 const char *prefix, size_t pfxlen) 455{ 456 struct exec_val *execp = &pred_ptr->args.exec_vec; 457 size_t len = strlen(pathname); 458 459 (void) stat_buf; 460 461 if (execp->multiple) 462 { 463 /* Push the argument onto the current list. 464 * The command may or may not be run at this point, 465 * depending on the command line length limits. 466 */ 467 bc_push_arg(&execp->ctl, 468 &execp->state, 469 pathname, len+1, 470 prefix, pfxlen, 471 0); 472 473 /* POSIX: If the primary expression is punctuated by a plus 474 * sign, the primary shall always evaluate as true 475 */ 476 return true; 477 } 478 else 479 { 480 int i; 481 482 for (i=0; i<execp->num_args; ++i) 483 { 484 bc_do_insert(&execp->ctl, 485 &execp->state, 486 execp->replace_vec[i], 487 strlen(execp->replace_vec[i]), 488 prefix, pfxlen, 489 pathname, len, 490 0); 491 } 492 493 /* Actually invoke the command. */ 494 return execp->ctl.exec_callback(&execp->ctl, 495 &execp->state); 496 } 497} 498 499 500boolean 501pred_exec (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 502{ 503 return new_impl_pred_exec(pathname, stat_buf, pred_ptr, NULL, 0); 504} 505 506boolean 507pred_execdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 508{ 509 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./"; 510 (void) &pathname; 511 return new_impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr, 512 prefix, (prefix ? 2 : 0)); 513} 514 515boolean 516pred_false (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 517{ 518 (void) &pathname; 519 (void) &stat_buf; 520 (void) &pred_ptr; 521 522 523 return (false); 524} 525 526boolean 527pred_fls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 528{ 529 list_file (pathname, state.rel_pathname, stat_buf, options.start_time, 530 options.output_block_size, pred_ptr->args.stream); 531 return (true); 532} 533 534boolean 535pred_fprint (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 536{ 537 (void) &pathname; 538 (void) &stat_buf; 539 540 print_quoted(pred_ptr->args.printf_vec.stream, 541 pred_ptr->args.printf_vec.quote_opts, 542 pred_ptr->args.printf_vec.dest_is_tty, 543 "%s\n", 544 pathname); 545 return true; 546} 547 548boolean 549pred_fprint0 (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 550{ 551 (void) &pathname; 552 (void) &stat_buf; 553 554 fputs (pathname, pred_ptr->args.stream); 555 putc (0, pred_ptr->args.stream); 556 return (true); 557} 558 559 560 561static char* 562mode_to_filetype(mode_t m) 563{ 564 return 565 m == S_IFSOCK ? "s" : 566 m == S_IFLNK ? "l" : 567 m == S_IFREG ? "f" : 568 m == S_IFBLK ? "b" : 569 m == S_IFDIR ? "d" : 570 m == S_IFCHR ? "c" : 571#ifdef S_IFDOOR 572 m == S_IFDOOR ? "D" : 573#endif 574 m == S_IFIFO ? "p" : "U"; 575} 576 577 578boolean 579pred_fprintf (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 580{ 581 FILE *fp = pred_ptr->args.printf_vec.stream; 582 const struct quoting_options *qopts = pred_ptr->args.printf_vec.quote_opts; 583 boolean ttyflag = pred_ptr->args.printf_vec.dest_is_tty; 584 struct segment *segment; 585 char *cp; 586 char hbuf[LONGEST_HUMAN_READABLE + 1]; 587 588 for (segment = pred_ptr->args.printf_vec.segment; segment; 589 segment = segment->next) 590 { 591 if (segment->kind & 0xff00) /* Component of date. */ 592 { 593 time_t t; 594 595 switch (segment->kind & 0xff) 596 { 597 case 'A': 598 t = stat_buf->st_atime; 599 break; 600 case 'C': 601 t = stat_buf->st_ctime; 602 break; 603 case 'T': 604 t = stat_buf->st_mtime; 605 break; 606 default: 607 abort (); 608 } 609 /* We trust the output of format_date not to contain 610 * nasty characters, though the value of the date 611 * is itself untrusted data. 612 */ 613 /* trusted */ 614 fprintf (fp, segment->text, 615 format_date (t, (segment->kind >> 8) & 0xff)); 616 continue; 617 } 618 619 switch (segment->kind) 620 { 621 case KIND_PLAIN: /* Plain text string (no % conversion). */ 622 /* trusted */ 623 fwrite (segment->text, 1, segment->text_len, fp); 624 break; 625 case KIND_STOP: /* Terminate argument and flush output. */ 626 /* trusted */ 627 fwrite (segment->text, 1, segment->text_len, fp); 628 fflush (fp); 629 return (true); 630 case 'a': /* atime in `ctime' format. */ 631 /* UNTRUSTED, probably unexploitable */ 632 fprintf (fp, segment->text, ctime_format (stat_buf->st_atime)); 633 break; 634 case 'b': /* size in 512-byte blocks */ 635 /* UNTRUSTED, probably unexploitable */ 636 fprintf (fp, segment->text, 637 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf), 638 hbuf, human_ceiling, 639 ST_NBLOCKSIZE, 512)); 640 break; 641 case 'c': /* ctime in `ctime' format */ 642 /* UNTRUSTED, probably unexploitable */ 643 fprintf (fp, segment->text, ctime_format (stat_buf->st_ctime)); 644 break; 645 case 'd': /* depth in search tree */ 646 /* UNTRUSTED, probably unexploitable */ 647 fprintf (fp, segment->text, state.curdepth); 648 break; 649 case 'D': /* Device on which file exists (stat.st_dev) */ 650 /* trusted */ 651 fprintf (fp, segment->text, 652 human_readable ((uintmax_t) stat_buf->st_dev, hbuf, 653 human_ceiling, 1, 1)); 654 break; 655 case 'f': /* base name of path */ 656 /* sanitised */ 657 { 658 char *base = base_name (pathname); 659 print_quoted (fp, qopts, ttyflag, segment->text, base); 660 free (base); 661 } 662 break; 663 case 'F': /* filesystem type */ 664 /* trusted */ 665 print_quoted (fp, qopts, ttyflag, segment->text, filesystem_type (stat_buf, pathname)); 666 break; 667 case 'g': /* group name */ 668 /* trusted */ 669 /* (well, the actual group is selected by the user but 670 * its name was selected by the system administrator) 671 */ 672 { 673 struct group *g; 674 675 g = getgrgid (stat_buf->st_gid); 676 if (g) 677 { 678 segment->text[segment->text_len] = 's'; 679 fprintf (fp, segment->text, g->gr_name); 680 break; 681 } 682 /* else fallthru */ 683 } 684 case 'G': /* GID number */ 685 /* UNTRUSTED, probably unexploitable */ 686 fprintf (fp, segment->text, 687 human_readable ((uintmax_t) stat_buf->st_gid, hbuf, 688 human_ceiling, 1, 1)); 689 break; 690 case 'h': /* leading directories part of path */ 691 /* sanitised */ 692 { 693 char cc; 694 695 cp = strrchr (pathname, '/'); 696 if (cp == NULL) /* No leading directories. */ 697 { 698 /* If there is no slash in the pathname, we still 699 * print the string because it contains characters 700 * other than just '%s'. The %h expands to ".". 701 */ 702 print_quoted (fp, qopts, ttyflag, segment->text, "."); 703 } 704 else 705 { 706 cc = *cp; 707 *cp = '\0'; 708 print_quoted (fp, qopts, ttyflag, segment->text, pathname); 709 *cp = cc; 710 } 711 break; 712 } 713 case 'H': /* ARGV element file was found under */ 714 /* trusted */ 715 { 716 char cc = pathname[state.path_length]; 717 718 pathname[state.path_length] = '\0'; 719 fprintf (fp, segment->text, pathname); 720 pathname[state.path_length] = cc; 721 break; 722 } 723 case 'i': /* inode number */ 724 /* UNTRUSTED, but not exploitable I think */ 725 fprintf (fp, segment->text, 726 human_readable ((uintmax_t) stat_buf->st_ino, hbuf, 727 human_ceiling, 728 1, 1)); 729 break; 730 case 'k': /* size in 1K blocks */ 731 /* UNTRUSTED, but not exploitable I think */ 732 fprintf (fp, segment->text, 733 human_readable ((uintmax_t) ST_NBLOCKS (*stat_buf), 734 hbuf, human_ceiling, 735 ST_NBLOCKSIZE, 1024)); 736 break; 737 case 'l': /* object of symlink */ 738 /* sanitised */ 739#ifdef S_ISLNK 740 { 741 char *linkname = 0; 742 743 if (S_ISLNK (stat_buf->st_mode)) 744 { 745 linkname = get_link_name (pathname, state.rel_pathname); 746 if (linkname == 0) 747 state.exit_status = 1; 748 } 749 if (linkname) 750 { 751 print_quoted (fp, qopts, ttyflag, segment->text, linkname); 752 free (linkname); 753 } 754 else 755 print_quoted (fp, qopts, ttyflag, segment->text, ""); 756 } 757#endif /* S_ISLNK */ 758 break; 759 760 case 'M': /* mode as 10 chars (eg., "-rwxr-x--x" */ 761 /* UNTRUSTED, probably unexploitable */ 762 { 763 char modestring[16] ; 764 filemodestring (stat_buf, modestring); 765 modestring[10] = '\0'; 766 fprintf (fp, segment->text, modestring); 767 } 768 break; 769 770 case 'm': /* mode as octal number (perms only) */ 771 /* UNTRUSTED, probably unexploitable */ 772 { 773 /* Output the mode portably using the traditional numbers, 774 even if the host unwisely uses some other numbering 775 scheme. But help the compiler in the common case where 776 the host uses the traditional numbering scheme. */ 777 mode_t m = stat_buf->st_mode; 778 boolean traditional_numbering_scheme = 779 (S_ISUID == 04000 && S_ISGID == 02000 && S_ISVTX == 01000 780 && S_IRUSR == 00400 && S_IWUSR == 00200 && S_IXUSR == 00100 781 && S_IRGRP == 00040 && S_IWGRP == 00020 && S_IXGRP == 00010 782 && S_IROTH == 00004 && S_IWOTH == 00002 && S_IXOTH == 00001); 783 fprintf (fp, segment->text, 784 (traditional_numbering_scheme 785 ? m & MODE_ALL 786 : ((m & S_ISUID ? 04000 : 0) 787 | (m & S_ISGID ? 02000 : 0) 788 | (m & S_ISVTX ? 01000 : 0) 789 | (m & S_IRUSR ? 00400 : 0) 790 | (m & S_IWUSR ? 00200 : 0) 791 | (m & S_IXUSR ? 00100 : 0) 792 | (m & S_IRGRP ? 00040 : 0) 793 | (m & S_IWGRP ? 00020 : 0) 794 | (m & S_IXGRP ? 00010 : 0) 795 | (m & S_IROTH ? 00004 : 0) 796 | (m & S_IWOTH ? 00002 : 0) 797 | (m & S_IXOTH ? 00001 : 0)))); 798 } 799 break; 800 801 case 'n': /* number of links */ 802 /* UNTRUSTED, probably unexploitable */ 803 fprintf (fp, segment->text, 804 human_readable ((uintmax_t) stat_buf->st_nlink, 805 hbuf, 806 human_ceiling, 807 1, 1)); 808 break; 809 case 'p': /* pathname */ 810 /* sanitised */ 811 print_quoted (fp, qopts, ttyflag, segment->text, pathname); 812 break; 813 case 'P': /* pathname with ARGV element stripped */ 814 /* sanitised */ 815 if (state.curdepth > 0) 816 { 817 cp = pathname + state.path_length; 818 if (*cp == '/') 819 /* Move past the slash between the ARGV element 820 and the rest of the pathname. But if the ARGV element 821 ends in a slash, we didn't add another, so we've 822 already skipped past it. */ 823 cp++; 824 } 825 else 826 cp = ""; 827 print_quoted (fp, qopts, ttyflag, segment->text, cp); 828 break; 829 case 's': /* size in bytes */ 830 /* UNTRUSTED, probably unexploitable */ 831 fprintf (fp, segment->text, 832 human_readable ((uintmax_t) stat_buf->st_size, 833 hbuf, human_ceiling, 1, 1)); 834 break; 835 case 't': /* mtime in `ctime' format */ 836 /* UNTRUSTED, probably unexploitable */ 837 fprintf (fp, segment->text, ctime_format (stat_buf->st_mtime)); 838 break; 839 case 'u': /* user name */ 840 /* trusted */ 841 /* (well, the actual user is selected by the user on systems 842 * where chown is not restricted, but the user name was 843 * selected by the system administrator) 844 */ 845 { 846 struct passwd *p; 847 848 p = getpwuid (stat_buf->st_uid); 849 if (p) 850 { 851 segment->text[segment->text_len] = 's'; 852 fprintf (fp, segment->text, p->pw_name); 853 break; 854 } 855 /* else fallthru */ 856 } 857 858 case 'U': /* UID number */ 859 /* UNTRUSTED, probably unexploitable */ 860 fprintf (fp, segment->text, 861 human_readable ((uintmax_t) stat_buf->st_uid, hbuf, 862 human_ceiling, 1, 1)); 863 break; 864 865 /* type of filesystem entry like `ls -l`: (d,-,l,s,p,b,c,n) n=nonexistent(symlink) */ 866 case 'Y': /* in case of symlink */ 867 /* trusted */ 868 { 869#ifdef S_ISLNK 870 if (S_ISLNK (stat_buf->st_mode)) 871 { 872 struct stat sbuf; 873 /* If we would normally follow links, do not do so. 874 * If we would normally not follow links, do so. 875 */ 876 if ((following_links() ? lstat : stat) 877 (state.rel_pathname, &sbuf) != 0) 878 { 879 if ( errno == ENOENT ) { 880 fprintf (fp, segment->text, "N"); 881 break; 882 }; 883 if ( errno == ELOOP ) { 884 fprintf (fp, segment->text, "L"); 885 break; 886 }; 887 error (0, errno, "%s", pathname); 888 /* exit_status = 1; 889 return (false); */ 890 } 891 fprintf (fp, segment->text, 892 mode_to_filetype(sbuf.st_mode & S_IFMT)); 893 } 894#endif /* S_ISLNK */ 895 else 896 { 897 fprintf (fp, segment->text, 898 mode_to_filetype(stat_buf->st_mode & S_IFMT)); 899 } 900 } 901 break; 902 903 case 'y': 904 /* trusted */ 905 { 906 fprintf (fp, segment->text, 907 mode_to_filetype(stat_buf->st_mode & S_IFMT)); 908 } 909 break; 910 } 911 } 912 return true; 913} 914 915boolean 916pred_fstype (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 917{ 918 (void) pathname; 919 920 if (strcmp (filesystem_type (stat_buf, pathname), pred_ptr->args.str) == 0) 921 return true; 922 else 923 return false; 924} 925 926boolean 927pred_gid (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 928{ 929 (void) pathname; 930 931 switch (pred_ptr->args.info.kind) 932 { 933 case COMP_GT: 934 if (stat_buf->st_gid > pred_ptr->args.info.l_val) 935 return (true); 936 break; 937 case COMP_LT: 938 if (stat_buf->st_gid < pred_ptr->args.info.l_val) 939 return (true); 940 break; 941 case COMP_EQ: 942 if (stat_buf->st_gid == pred_ptr->args.info.l_val) 943 return (true); 944 break; 945 } 946 return (false); 947} 948 949boolean 950pred_group (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 951{ 952 (void) pathname; 953 954 if (pred_ptr->args.gid == stat_buf->st_gid) 955 return (true); 956 else 957 return (false); 958} 959 960boolean 961pred_ilname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 962{ 963 return insert_lname (pathname, stat_buf, pred_ptr, true); 964} 965 966/* Common code between -name, -iname. PATHNAME is being visited, STR 967 is name to compare basename against, and FLAGS are passed to 968 fnmatch. Recall that 'find / -name /' is one of the few times where a '/' 969 in the -name must actually find something. */ 970static boolean 971pred_name_common (const char *pathname, const char *str, int flags) 972{ 973 char *p; 974 boolean b; 975 /* We used to use last_component() here, but that would not allow us 976 * to modify the input string, which is const. We could optimise by 977 * duplicating the string only if we need to modify it, and I'll do 978 * that if there is a measurable performance difference on a machine 979 * built after 1990... 980 */ 981 char *base = base_name (pathname); 982 /* remove trailing slashes, but leave "/" or "//foo" unchanged. */ 983 strip_trailing_slashes(base); 984 985 /* FNM_PERIOD is not used here because POSIX requires that it not be. 986 * See http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-126.html 987 */ 988 b = fnmatch (str, base, flags) == 0; 989 free (base); 990 return b; 991} 992 993 994boolean 995pred_iname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 996{ 997 (void) stat_buf; 998 return pred_name_common (pathname, pred_ptr->args.str, FNM_CASEFOLD); 999} 1000 1001boolean 1002pred_inum (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1003{ 1004 (void) pathname; 1005 1006 switch (pred_ptr->args.info.kind) 1007 { 1008 case COMP_GT: 1009 if (stat_buf->st_ino > pred_ptr->args.info.l_val) 1010 return (true); 1011 break; 1012 case COMP_LT: 1013 if (stat_buf->st_ino < pred_ptr->args.info.l_val) 1014 return (true); 1015 break; 1016 case COMP_EQ: 1017 if (stat_buf->st_ino == pred_ptr->args.info.l_val) 1018 return (true); 1019 break; 1020 } 1021 return (false); 1022} 1023 1024boolean 1025pred_ipath (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1026{ 1027 (void) stat_buf; 1028 1029 if (fnmatch (pred_ptr->args.str, pathname, FNM_CASEFOLD) == 0) 1030 return (true); 1031 return (false); 1032} 1033 1034boolean 1035pred_links (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1036{ 1037 (void) pathname; 1038 1039 switch (pred_ptr->args.info.kind) 1040 { 1041 case COMP_GT: 1042 if (stat_buf->st_nlink > pred_ptr->args.info.l_val) 1043 return (true); 1044 break; 1045 case COMP_LT: 1046 if (stat_buf->st_nlink < pred_ptr->args.info.l_val) 1047 return (true); 1048 break; 1049 case COMP_EQ: 1050 if (stat_buf->st_nlink == pred_ptr->args.info.l_val) 1051 return (true); 1052 break; 1053 } 1054 return (false); 1055} 1056 1057boolean 1058pred_lname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1059{ 1060 return insert_lname (pathname, stat_buf, pred_ptr, false); 1061} 1062 1063static boolean 1064insert_lname (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr, boolean ignore_case) 1065{ 1066 boolean ret = false; 1067#ifdef S_ISLNK 1068 if (S_ISLNK (stat_buf->st_mode)) 1069 { 1070 char *linkname = get_link_name (pathname, state.rel_pathname); 1071 if (linkname) 1072 { 1073 if (fnmatch (pred_ptr->args.str, linkname, 1074 ignore_case ? FNM_CASEFOLD : 0) == 0) 1075 ret = true; 1076 free (linkname); 1077 } 1078 } 1079#endif /* S_ISLNK */ 1080 return (ret); 1081} 1082 1083boolean 1084pred_ls (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1085{ 1086 (void) pred_ptr; 1087 1088 list_file (pathname, state.rel_pathname, stat_buf, options.start_time, 1089 options.output_block_size, stdout); 1090 return (true); 1091} 1092 1093boolean 1094pred_mmin (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1095{ 1096 (void) &pathname; 1097 return pred_timewindow(stat_buf->st_mtime, pred_ptr, 60); 1098} 1099 1100boolean 1101pred_mtime (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1102{ 1103 (void) pathname; 1104 return pred_timewindow(stat_buf->st_mtime, pred_ptr, DAYSECS); 1105} 1106 1107boolean 1108pred_name (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1109{ 1110 (void) stat_buf; 1111 return pred_name_common (pathname, pred_ptr->args.str, 0); 1112} 1113 1114boolean 1115pred_negate (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1116{ 1117 /* Check whether we need a stat here. */ 1118 /* TODO: what about need_type? */ 1119 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0) 1120 return false; 1121 return (!(*pred_ptr->pred_right->pred_func) (pathname, stat_buf, 1122 pred_ptr->pred_right)); 1123} 1124 1125boolean 1126pred_newer (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1127{ 1128 (void) pathname; 1129 1130 if (stat_buf->st_mtime > pred_ptr->args.time) 1131 return (true); 1132 return (false); 1133} 1134 1135boolean 1136pred_nogroup (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1137{ 1138 (void) pathname; 1139 (void) pred_ptr; 1140 1141#ifdef CACHE_IDS 1142 extern char *gid_unused; 1143 1144 return gid_unused[(unsigned) stat_buf->st_gid]; 1145#else 1146 return getgrgid (stat_buf->st_gid) == NULL; 1147#endif 1148} 1149 1150boolean 1151pred_nouser (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1152{ 1153#ifdef CACHE_IDS 1154 extern char *uid_unused; 1155#endif 1156 1157 (void) pathname; 1158 (void) pred_ptr; 1159 1160#ifdef CACHE_IDS 1161 return uid_unused[(unsigned) stat_buf->st_uid]; 1162#else 1163 return getpwuid (stat_buf->st_uid) == NULL; 1164#endif 1165} 1166 1167 1168static boolean 1169is_ok(const char *program, const char *arg) 1170{ 1171 fflush (stdout); 1172 /* The draft open standard requires that, in the POSIX locale, 1173 the last non-blank character of this prompt be '?'. 1174 The exact format is not specified. 1175 This standard does not have requirements for locales other than POSIX 1176 */ 1177 /* XXX: printing UNTRUSTED data here. */ 1178 fprintf (stderr, _("< %s ... %s > ? "), program, arg); 1179 fflush (stderr); 1180 return yesno(); 1181} 1182 1183boolean 1184pred_ok (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1185{ 1186 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname)) 1187 return new_impl_pred_exec (pathname, stat_buf, pred_ptr, NULL, 0); 1188 else 1189 return false; 1190} 1191 1192boolean 1193pred_okdir (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1194{ 1195 const char *prefix = (state.rel_pathname[0] == '/') ? NULL : "./"; 1196 if (is_ok(pred_ptr->args.exec_vec.replace_vec[0], pathname)) 1197 return new_impl_pred_exec (state.rel_pathname, stat_buf, pred_ptr, 1198 prefix, (prefix ? 2 : 0)); 1199 else 1200 return false; 1201} 1202 1203boolean 1204pred_openparen (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1205{ 1206 (void) pathname; 1207 (void) stat_buf; 1208 (void) pred_ptr; 1209 return true; 1210} 1211 1212boolean 1213pred_or (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1214{ 1215 if (pred_ptr->pred_left == NULL 1216 || !(*pred_ptr->pred_left->pred_func) (pathname, stat_buf, 1217 pred_ptr->pred_left)) 1218 { 1219 if (get_info(pathname, state.rel_pathname, stat_buf, pred_ptr) != 0) 1220 return false; 1221 return ((*pred_ptr->pred_right->pred_func) (pathname, stat_buf, 1222 pred_ptr->pred_right)); 1223 } 1224 else 1225 return true; 1226} 1227 1228boolean 1229pred_path (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1230{ 1231 (void) stat_buf; 1232 if (fnmatch (pred_ptr->args.str, pathname, 0) == 0) 1233 return (true); 1234 return (false); 1235} 1236 1237boolean 1238pred_perm (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1239{ 1240 mode_t mode = stat_buf->st_mode; 1241 mode_t perm_val = pred_ptr->args.perm.val[S_ISDIR (mode) != 0]; 1242 (void) pathname; 1243 switch (pred_ptr->args.perm.kind) 1244 { 1245 case PERM_AT_LEAST: 1246 return (mode & perm_val) == perm_val; 1247 break; 1248 1249 case PERM_ANY: 1250 /* True if any of the bits set in the mask are also set in the file's mode. 1251 * 1252 * 1253 * Otherwise, if onum is prefixed by a hyphen, the primary shall 1254 * evaluate as true if at least all of the bits specified in 1255 * onum that are also set in the octal mask 07777 are set. 1256 * 1257 * Eric Blake's interpretation is that the mode argument is zero, 1258 1259 */ 1260 if (0 == perm_val) 1261 return true; /* Savannah bug 14748; we used to return false */ 1262 else 1263 return (mode & perm_val) != 0; 1264 break; 1265 1266 case PERM_EXACT: 1267 return (mode & MODE_ALL) == perm_val; 1268 break; 1269 1270 default: 1271 abort (); 1272 break; 1273 } 1274} 1275 1276boolean 1277pred_print (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1278{ 1279 (void) stat_buf; 1280 (void) pred_ptr; 1281 /* puts (pathname); */ 1282 print_quoted(pred_ptr->args.printf_vec.stream, 1283 pred_ptr->args.printf_vec.quote_opts, 1284 pred_ptr->args.printf_vec.dest_is_tty, 1285 "%s\n", pathname); 1286 return true; 1287} 1288 1289boolean 1290pred_print0 (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1291{ 1292 (void) stat_buf; 1293 (void) pred_ptr; 1294 fputs (pathname, stdout); 1295 putc (0, stdout); 1296 return (true); 1297} 1298 1299boolean 1300pred_prune (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1301{ 1302 (void) pathname; 1303 (void) stat_buf; 1304 (void) pred_ptr; 1305 state.stop_at_current_level = true; 1306 return (options.do_dir_first); /* This is what SunOS find seems to do. */ 1307} 1308 1309boolean 1310pred_quit (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1311{ 1312 (void) pathname; 1313 (void) stat_buf; 1314 (void) pred_ptr; 1315 1316 /* Run any cleanups. This includes executing any command lines 1317 * we have partly built but not executed. 1318 */ 1319 cleanup(); 1320 1321 /* Since -exec and friends don't leave child processes running in the 1322 * background, there is no need to wait for them here. 1323 */ 1324 exit(state.exit_status); /* 0 for success, etc. */ 1325} 1326 1327boolean 1328pred_regex (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1329{ 1330 int len = strlen (pathname); 1331(void) stat_buf; 1332 if (re_match (pred_ptr->args.regex, pathname, len, 0, 1333 (struct re_registers *) NULL) == len) 1334 return (true); 1335 return (false); 1336} 1337 1338boolean 1339pred_size (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1340{ 1341 uintmax_t f_val; 1342 1343 (void) pathname; 1344 f_val = ((stat_buf->st_size / pred_ptr->args.size.blocksize) 1345 + (stat_buf->st_size % pred_ptr->args.size.blocksize != 0)); 1346 switch (pred_ptr->args.size.kind) 1347 { 1348 case COMP_GT: 1349 if (f_val > pred_ptr->args.size.size) 1350 return (true); 1351 break; 1352 case COMP_LT: 1353 if (f_val < pred_ptr->args.size.size) 1354 return (true); 1355 break; 1356 case COMP_EQ: 1357 if (f_val == pred_ptr->args.size.size) 1358 return (true); 1359 break; 1360 } 1361 return (false); 1362} 1363 1364boolean 1365pred_samefile (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1366{ 1367 /* Potential optimisation: because of the loop protection, we always 1368 * know the device of the current directory, hence the device number 1369 * of the file we're currently considering. If -L is not in effect, 1370 * and the device number of the file we're looking for is not the 1371 * same as the device number of the current directory, this 1372 * predicate cannot return true. Hence there would be no need to 1373 * stat the file we're lookingn at. 1374 */ 1375 (void) pathname; 1376 1377 return stat_buf->st_ino == pred_ptr->args.fileid.ino 1378 && stat_buf->st_dev == pred_ptr->args.fileid.dev; 1379} 1380 1381boolean 1382pred_true (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1383{ 1384 (void) pathname; 1385 (void) stat_buf; 1386 (void) pred_ptr; 1387 return true; 1388} 1389 1390boolean 1391pred_type (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1392{ 1393 mode_t mode; 1394 mode_t type = pred_ptr->args.type; 1395 1396 assert(state.have_type); 1397 assert(state.type != 0); 1398 1399 (void) pathname; 1400 1401 if (state.have_stat) 1402 mode = stat_buf->st_mode; 1403 else 1404 mode = state.type; 1405 1406#ifndef S_IFMT 1407 /* POSIX system; check `mode' the slow way. */ 1408 if ((S_ISBLK (mode) && type == S_IFBLK) 1409 || (S_ISCHR (mode) && type == S_IFCHR) 1410 || (S_ISDIR (mode) && type == S_IFDIR) 1411 || (S_ISREG (mode) && type == S_IFREG) 1412#ifdef S_IFLNK 1413 || (S_ISLNK (mode) && type == S_IFLNK) 1414#endif 1415#ifdef S_IFIFO 1416 || (S_ISFIFO (mode) && type == S_IFIFO) 1417#endif 1418#ifdef S_IFSOCK 1419 || (S_ISSOCK (mode) && type == S_IFSOCK) 1420#endif 1421#ifdef S_IFDOOR 1422 || (S_ISDOOR (mode) && type == S_IFDOOR) 1423#endif 1424 ) 1425#else /* S_IFMT */ 1426 /* Unix system; check `mode' the fast way. */ 1427 if ((mode & S_IFMT) == type) 1428#endif /* S_IFMT */ 1429 return (true); 1430 else 1431 return (false); 1432} 1433 1434boolean 1435pred_uid (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1436{ 1437 (void) pathname; 1438 switch (pred_ptr->args.info.kind) 1439 { 1440 case COMP_GT: 1441 if (stat_buf->st_uid > pred_ptr->args.info.l_val) 1442 return (true); 1443 break; 1444 case COMP_LT: 1445 if (stat_buf->st_uid < pred_ptr->args.info.l_val) 1446 return (true); 1447 break; 1448 case COMP_EQ: 1449 if (stat_buf->st_uid == pred_ptr->args.info.l_val) 1450 return (true); 1451 break; 1452 } 1453 return (false); 1454} 1455 1456boolean 1457pred_used (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1458{ 1459 time_t delta; 1460 1461 (void) pathname; 1462 delta = stat_buf->st_atime - stat_buf->st_ctime; /* Use difftime? */ 1463 return pred_timewindow(delta, pred_ptr, DAYSECS); 1464} 1465 1466boolean 1467pred_user (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1468{ 1469 (void) pathname; 1470 if (pred_ptr->args.uid == stat_buf->st_uid) 1471 return (true); 1472 else 1473 return (false); 1474} 1475 1476boolean 1477pred_xtype (char *pathname, struct stat *stat_buf, struct predicate *pred_ptr) 1478{ 1479 struct stat sbuf; /* local copy, not stat_buf because we're using a different stat method */ 1480 int (*ystat) (const char*, struct stat *p); 1481 1482 /* If we would normally stat the link itself, stat the target instead. 1483 * If we would normally follow the link, stat the link itself instead. 1484 */ 1485 if (following_links()) 1486 ystat = optionp_stat; 1487 else 1488 ystat = optionl_stat; 1489 1490 if ((*ystat) (state.rel_pathname, &sbuf) != 0) 1491 { 1492 if (following_links() && errno == ENOENT) 1493 { 1494 /* If we failed to follow the symlink, 1495 * fall back on looking at the symlink itself. 1496 */ 1497 /* Mimic behavior of ls -lL. */ 1498 return (pred_type (pathname, stat_buf, pred_ptr)); 1499 } 1500 else 1501 { 1502 error (0, errno, "%s", pathname); 1503 state.exit_status = 1; 1504 } 1505 return false; 1506 } 1507 /* Now that we have our stat() information, query it in the same 1508 * way that -type does. 1509 */ 1510 return (pred_type (pathname, &sbuf, pred_ptr)); 1511} 1512 1513/* 1) fork to get a child; parent remembers the child pid 1514 2) child execs the command requested 1515 3) parent waits for child; checks for proper pid of child 1516 1517 Possible returns: 1518 1519 ret errno status(h) status(l) 1520 1521 pid x signal# 0177 stopped 1522 pid x exit arg 0 term by _exit 1523 pid x 0 signal # term by signal 1524 -1 EINTR parent got signal 1525 -1 other some other kind of error 1526 1527 Return true only if the pid matches, status(l) is 1528 zero, and the exit arg (status high) is 0. 1529 Otherwise return false, possibly printing an error message. */ 1530 1531 1532static void 1533prep_child_for_exec (boolean close_stdin) 1534{ 1535 if (close_stdin) 1536 { 1537 const char inputfile[] = "/dev/null"; 1538 /* fprintf(stderr, "attaching stdin to /dev/null\n"); */ 1539 1540 close(0); 1541 if (open(inputfile, O_RDONLY) < 0) 1542 { 1543 /* This is not entirely fatal, since 1544 * executing the child with a closed 1545 * stdin is almost as good as executing it 1546 * with its stdin attached to /dev/null. 1547 */ 1548 error (0, errno, "%s", inputfile); 1549 } 1550 } 1551} 1552 1553 1554 1555int 1556launch (const struct buildcmd_control *ctl, 1557 struct buildcmd_state *buildstate) 1558{ 1559 int wait_status; 1560 pid_t child_pid; 1561 static int first_time = 1; 1562 const struct exec_val *execp = buildstate->usercontext; 1563 1564 /* Null terminate the arg list. */ 1565 bc_push_arg (ctl, buildstate, (char *) NULL, 0, NULL, 0, false); 1566 1567 /* Make sure output of command doesn't get mixed with find output. */ 1568 fflush (stdout); 1569 fflush (stderr); 1570 1571 /* Make sure to listen for the kids. */ 1572 if (first_time) 1573 { 1574 first_time = 0; 1575 signal (SIGCHLD, SIG_DFL); 1576 } 1577 1578 child_pid = fork (); 1579 if (child_pid == -1) 1580 error (1, errno, _("cannot fork")); 1581 if (child_pid == 0) 1582 { 1583 /* We be the child. */ 1584 prep_child_for_exec(execp->close_stdin); 1585 1586 /* For -exec and -ok, change directory back to the starting directory. 1587 * for -execdir and -okdir, stay in the directory we are searching 1588 * (the latter is more secure). 1589 */ 1590 if (!execp->use_current_dir) 1591 { 1592 /* Even if DEBUG_STAT is set, don't announce our change of 1593 * directory, since we're not going to emit a subsequent 1594 * announcement of a call to stat() anyway, as we're about 1595 * to exec something. 1596 */ 1597 if (starting_desc < 0 1598 ? chdir (starting_dir) != 0 1599 : fchdir (starting_desc) != 0) 1600 { 1601 error (0, errno, "%s", starting_dir); 1602 _exit (1); 1603 } 1604 } 1605 1606 execvp (buildstate->cmd_argv[0], buildstate->cmd_argv); 1607 error (0, errno, "%s", buildstate->cmd_argv[0]); 1608 _exit (1); 1609 } 1610 1611 1612 /* In parent; set up for next time. */ 1613 bc_clear_args(ctl, buildstate); 1614 1615 1616 while (waitpid (child_pid, &wait_status, 0) == (pid_t) -1) 1617 { 1618 if (errno != EINTR) 1619 { 1620 error (0, errno, _("error waiting for %s"), buildstate->cmd_argv[0]); 1621 state.exit_status = 1; 1622 return 0; /* FAIL */ 1623 } 1624 } 1625 1626 if (WIFSIGNALED (wait_status)) 1627 { 1628 error (0, 0, _("%s terminated by signal %d"), 1629 buildstate->cmd_argv[0], WTERMSIG (wait_status)); 1630 1631 if (execp->multiple) 1632 { 1633 /* -exec \; just returns false if the invoked command fails. 1634 * -exec {} + returns true if the invoked command fails, but 1635 * sets the program exit status. 1636 */ 1637 state.exit_status = 1; 1638 } 1639 1640 return 1; /* OK */ 1641 } 1642 1643 if (0 == WEXITSTATUS (wait_status)) 1644 { 1645 return 1; /* OK */ 1646 } 1647 else 1648 { 1649 if (execp->multiple) 1650 { 1651 /* -exec \; just returns false if the invoked command fails. 1652 * -exec {} + returns true if the invoked command fails, but 1653 * sets the program exit status. 1654 */ 1655 state.exit_status = 1; 1656 } 1657 return 0; /* FAIL */ 1658 } 1659 1660} 1661 1662 1663/* Return a static string formatting the time WHEN according to the 1664 strftime format character KIND. */ 1665 1666static char * 1667format_date (time_t when, int kind) 1668{ 1669 static char buf[MAX (LONGEST_HUMAN_READABLE + 2, 64)]; 1670 struct tm *tm; 1671 char fmt[6]; 1672 1673 fmt[0] = '%'; 1674 fmt[1] = kind; 1675 fmt[2] = '\0'; 1676 if (kind == '+') 1677 strcpy (fmt, "%F+%T"); 1678 1679 if (kind != '@' 1680 && (tm = localtime (&when)) 1681 && strftime (buf, sizeof buf, fmt, tm)) 1682 return buf; 1683 else 1684 { 1685 uintmax_t w = when; 1686 char *p = human_readable (when < 0 ? -w : w, buf + 1, 1687 human_ceiling, 1, 1); 1688 if (when < 0) 1689 *--p = '-'; 1690 return p; 1691 } 1692} 1693 1694static char * 1695ctime_format (time_t when) 1696{ 1697 char *r = ctime (&when); 1698 if (!r) 1699 { 1700 /* The time cannot be represented as a struct tm. 1701 Output it as an integer. */ 1702 return format_date (when, '@'); 1703 } 1704 else 1705 { 1706 /* Remove the trailing newline from the ctime output, 1707 being careful not to assume that the output is fixed-width. */ 1708 *strchr (r, '\n') = '\0'; 1709 return r; 1710 } 1711} 1712 1713#ifdef DEBUG 1714/* Return a pointer to the string representation of 1715 the predicate function PRED_FUNC. */ 1716 1717char * 1718find_pred_name (pred_func) 1719 PFB pred_func; 1720{ 1721 int i; 1722 1723 for (i = 0; pred_table[i].pred_func != 0; i++) 1724 if (pred_table[i].pred_func == pred_func) 1725 break; 1726 return (pred_table[i].pred_name); 1727} 1728 1729static char * 1730type_name (type) 1731 short type; 1732{ 1733 int i; 1734 1735 for (i = 0; type_table[i].type != (short) -1; i++) 1736 if (type_table[i].type == type) 1737 break; 1738 return (type_table[i].type_name); 1739} 1740 1741static char * 1742prec_name (prec) 1743 short prec; 1744{ 1745 int i; 1746 1747 for (i = 0; prec_table[i].prec != (short) -1; i++) 1748 if (prec_table[i].prec == prec) 1749 break; 1750 return (prec_table[i].prec_name); 1751} 1752 1753/* Walk the expression tree NODE to stdout. 1754 INDENT is the number of levels to indent the left margin. */ 1755 1756void 1757print_tree (FILE *fp, struct predicate *node, int indent) 1758{ 1759 int i; 1760 1761 if (node == NULL) 1762 return; 1763 for (i = 0; i < indent; i++) 1764 fprintf (fp, " "); 1765 fprintf (fp, "pred = %s type = %s prec = %s addr = %p\n", 1766 find_pred_name (node->pred_func), 1767 type_name (node->p_type), prec_name (node->p_prec), node); 1768 if (node->need_stat || node->need_type) 1769 { 1770 int comma = 0; 1771 1772 for (i = 0; i < indent; i++) 1773 fprintf (fp, " "); 1774 1775 fprintf (fp, "Needs "); 1776 if (node->need_stat) 1777 { 1778 fprintf (fp, "stat"); 1779 comma = 1; 1780 } 1781 if (node->need_type) 1782 { 1783 fprintf (fp, "%stype", comma ? "," : ""); 1784 } 1785 fprintf (fp, "\n"); 1786 } 1787 1788 for (i = 0; i < indent; i++) 1789 fprintf (fp, " "); 1790 fprintf (fp, "left:\n"); 1791 print_tree (fp, node->pred_left, indent + 1); 1792 for (i = 0; i < indent; i++) 1793 fprintf (fp, " "); 1794 fprintf (fp, "right:\n"); 1795 print_tree (fp, node->pred_right, indent + 1); 1796} 1797 1798/* Copy STR into BUF and trim blanks from the end of BUF. 1799 Return BUF. */ 1800 1801static char * 1802blank_rtrim (str, buf) 1803 char *str; 1804 char *buf; 1805{ 1806 int i; 1807 1808 if (str == NULL) 1809 return (NULL); 1810 strcpy (buf, str); 1811 i = strlen (buf) - 1; 1812 while ((i >= 0) && ((buf[i] == ' ') || buf[i] == '\t')) 1813 i--; 1814 buf[++i] = '\0'; 1815 return (buf); 1816} 1817 1818/* Print out the predicate list starting at NODE. */ 1819 1820void 1821print_list (FILE *fp, struct predicate *node) 1822{ 1823 struct predicate *cur; 1824 char name[256]; 1825 1826 cur = node; 1827 while (cur != NULL) 1828 { 1829 fprintf (fp, "%s ", blank_rtrim (find_pred_name (cur->pred_func), name)); 1830 cur = cur->pred_next; 1831 } 1832 fprintf (fp, "\n"); 1833} 1834 1835 1836/* Print out the predicate list starting at NODE. */ 1837 1838 1839static void 1840print_parenthesised(FILE *fp, struct predicate *node) 1841{ 1842 int parens = 0; 1843 1844 if (node) 1845 { 1846 if ( ( (node->pred_func == pred_or) 1847 || (node->pred_func == pred_and) ) 1848 && node->pred_left == NULL) 1849 { 1850 /* We print "<nothing> or X" as just "X" 1851 * We print "<nothing> and X" as just "X" 1852 */ 1853 print_parenthesised(fp, node->pred_right); 1854 } 1855 else 1856 { 1857 if (node->pred_left || node->pred_right) 1858 parens = 1; 1859 1860 if (parens) 1861 fprintf(fp, "%s", " ( "); 1862 print_optlist(fp, node); 1863 if (parens) 1864 fprintf(fp, "%s", " ) "); 1865 } 1866 } 1867} 1868 1869void 1870print_optlist (FILE *fp, struct predicate *p) 1871{ 1872 char name[256]; 1873 1874 if (p) 1875 { 1876 print_parenthesised(fp, p->pred_left); 1877 fprintf (fp, 1878 "%s%s%s ", 1879 p->need_stat ? "[stat called here] " : "", 1880 p->need_type ? "[type needed here] " : "", 1881 blank_rtrim (find_pred_name (p->pred_func), name)); 1882 print_parenthesised(fp, p->pred_right); 1883 } 1884} 1885 1886#endif /* DEBUG */ 1887 1888 1889void 1890pred_sanity_check(const struct predicate *predicates) 1891{ 1892 const struct predicate *p; 1893 1894 for (p=predicates; p != NULL; p=p->pred_next) 1895 { 1896 /* All predicates must do something. */ 1897 assert(p->pred_func != NULL); 1898 1899 /* All predicates must have a parser table entry. */ 1900 assert(p->parser_entry != NULL); 1901 1902 /* If the parser table tells us that just one predicate function is 1903 * possible, verify that that is still the one that is in effect. 1904 * If the parser has NULL for the predicate function, that means that 1905 * the parse_xxx function fills it in, so we can't check it. 1906 */ 1907 if (p->parser_entry->pred_func) 1908 { 1909 assert(p->parser_entry->pred_func == p->pred_func); 1910 } 1911 1912 switch (p->parser_entry->type) 1913 { 1914 /* Options all take effect during parsing, so there should 1915 * be no predicate entries corresponding to them. Hence we 1916 * should not see any ARG_OPTION or ARG_POSITIONAL_OPTION 1917 * items. 1918 * 1919 * This is a silly way of coding this test, but it prevents 1920 * a compiler warning (i.e. otherwise it would think that 1921 * there would be case statements missing). 1922 */ 1923 case ARG_OPTION: 1924 case ARG_POSITIONAL_OPTION: 1925 assert(p->parser_entry->type != ARG_OPTION); 1926 assert(p->parser_entry->type != ARG_POSITIONAL_OPTION); 1927 break; 1928 1929 case ARG_ACTION: 1930 assert(p->side_effects); /* actions have side effects. */ 1931 if (p->pred_func != pred_prune && p->pred_func != pred_quit) 1932 { 1933 /* actions other than -prune and -quit should 1934 * inhibit the default -print 1935 */ 1936 assert(p->no_default_print); 1937 } 1938 break; 1939 1940 case ARG_PUNCTUATION: 1941 case ARG_TEST: 1942 /* Punctuation and tests should have no side 1943 * effects and not inhibit default print. 1944 */ 1945 assert(!p->no_default_print); 1946 assert(!p->side_effects); 1947 break; 1948 1949 } 1950 } 1951} 1952