1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Cimarron D. Taylor of the University of California, Berkeley. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 26 unchanged lines hidden (view full) --- 35 */ 36 37#ifndef lint 38#if 0 39static const char sccsid[] = "@(#)function.c 8.10 (Berkeley) 5/4/95"; 40#endif 41#endif /* not lint */ 42#include <sys/cdefs.h> |
43__FBSDID("$FreeBSD: head/usr.bin/find/function.c 97736 2002-06-02 12:57:41Z tjr $"); |
44 45#include <sys/param.h> 46#include <sys/ucred.h> 47#include <sys/stat.h> 48#include <sys/wait.h> 49#include <sys/mount.h> 50#include <sys/timeb.h> 51 52#include <dirent.h> 53#include <err.h> 54#include <errno.h> 55#include <fnmatch.h> 56#include <fts.h> 57#include <grp.h> |
58#include <limits.h> |
59#include <pwd.h> 60#include <regex.h> 61#include <stdio.h> 62#include <stdlib.h> 63#include <string.h> 64#include <unistd.h> 65 66#include "find.h" --- 457 unchanged lines hidden (view full) --- 524 FTSENT *entry; 525{ 526 extern int dotfd; 527 int cnt; 528 pid_t pid; 529 int status; 530 char *file; 531 |
532 if (entry == NULL && plan->flags & F_EXECPLUS) { 533 if (plan->e_ppos == plan->e_pbnum) 534 return (1); 535 plan->e_argv[plan->e_ppos] = NULL; 536 goto doexec; 537 } 538 |
539 /* XXX - if file/dir ends in '/' this will not work -- can it? */ 540 if ((plan->flags & F_EXECDIR) && \ 541 (file = strrchr(entry->fts_path, '/'))) 542 file++; 543 else 544 file = entry->fts_path; 545 |
546 if (plan->flags & F_EXECPLUS) { 547 if ((plan->e_argv[plan->e_ppos] = strdup(file)) == NULL) 548 err(1, NULL); 549 plan->e_len[plan->e_ppos] = strlen(file); 550 plan->e_psize += plan->e_len[plan->e_ppos]; 551 if (++plan->e_ppos < plan->e_pnummax && 552 plan->e_psize < plan->e_psizemax) 553 return (1); 554 plan->e_argv[plan->e_ppos] = NULL; 555 } else { 556 for (cnt = 0; plan->e_argv[cnt]; ++cnt) 557 if (plan->e_len[cnt]) 558 brace_subst(plan->e_orig[cnt], 559 &plan->e_argv[cnt], file, 560 plan->e_len[cnt]); 561 } |
562 |
563doexec: if ((plan->flags & F_NEEDOK) && !queryuser(plan->e_argv)) |
564 return 0; 565 566 /* make sure find output is interspersed correctly with subprocesses */ 567 fflush(stdout); 568 fflush(stderr); 569 570 switch (pid = fork()) { 571 case -1: --- 4 unchanged lines hidden (view full) --- 576 if (!(plan->flags & F_EXECDIR) && fchdir(dotfd)) { 577 warn("chdir"); 578 _exit(1); 579 } 580 execvp(plan->e_argv[0], plan->e_argv); 581 warn("%s", plan->e_argv[0]); 582 _exit(1); 583 } |
584 if (plan->flags & F_EXECPLUS) { 585 while (--plan->e_ppos >= plan->e_pbnum) 586 free(plan->e_argv[plan->e_ppos]); 587 plan->e_ppos = plan->e_pbnum; 588 plan->e_psize = plan->e_pbsize; 589 } |
590 pid = waitpid(pid, &status, 0); 591 return (pid != -1 && WIFEXITED(status) && !WEXITSTATUS(status)); 592} 593 594/* 595 * c_exec, c_execdir, c_ok -- 596 * build three parallel arrays, one with pointers to the strings passed 597 * on the command line, one with (possibly duplicated) pointers to the 598 * argv array, and one with integer values that are lengths of the 599 * strings, but also flags meaning that the string has to be massaged. 600 */ 601PLAN * 602c_exec(option, argvp) 603 OPTION *option; 604 char ***argvp; 605{ 606 PLAN *new; /* node returned */ |
607 long argmax; 608 int cnt, i; |
609 char **argv, **ap, *p; 610 611 /* XXX - was in c_execdir, but seems unnecessary!? 612 ftsoptions &= ~FTS_NOSTAT; 613 */ 614 isoutput = 1; 615 616 /* XXX - this is a change from the previous coding */ 617 new = palloc(option); 618 619 for (ap = argv = *argvp;; ++ap) { 620 if (!*ap) 621 errx(1, 622 "%s: no terminating \";\"", option->name); 623 if (**ap == ';') 624 break; |
625 if (**ap == '+' && ap != argv && strcmp(*(ap - 1), "{}") == 0) { 626 new->flags |= F_EXECPLUS; 627 break; 628 } |
629 } 630 631 if (ap == argv) 632 errx(1, "%s: no command specified", option->name); 633 634 cnt = ap - *argvp + 1; |
635 if (new->flags & F_EXECPLUS) { 636 new->e_ppos = new->e_pbnum = cnt - 2; 637 if ((argmax = sysconf(_SC_ARG_MAX)) == -1) { 638 warn("sysconf(_SC_ARG_MAX)"); 639 argmax = _POSIX_ARG_MAX; 640 } 641 /* 642 * Estimate the maximum number of arguments as {ARG_MAX}/10, 643 * and the maximum number of bytes to use for arguments as 644 * {ARG_MAX}*(3/4). 645 */ 646 new->e_pnummax = argmax / 10; 647 new->e_psizemax = (argmax / 4) * 3; 648 new->e_pbsize = 0; 649 cnt += new->e_pnummax + 1; 650 } |
651 if ((new->e_argv = malloc(cnt * sizeof(char *))) == NULL) 652 err(1, NULL); 653 if ((new->e_orig = malloc(cnt * sizeof(char *))) == NULL) 654 err(1, NULL); 655 if ((new->e_len = malloc(cnt * sizeof(int))) == NULL) 656 err(1, NULL); 657 658 for (argv = *argvp, cnt = 0; argv < ap; ++argv, ++cnt) { 659 new->e_orig[cnt] = *argv; |
660 if (new->flags & F_EXECPLUS) 661 new->e_pbsize += strlen(*argv) + 1; |
662 for (p = *argv; *p; ++p) |
663 if (!(new->flags & F_EXECPLUS) && p[0] == '{' && 664 p[1] == '}') { |
665 if ((new->e_argv[cnt] = 666 malloc(MAXPATHLEN)) == NULL) 667 err(1, NULL); 668 new->e_len[cnt] = MAXPATHLEN; 669 break; 670 } 671 if (!*p) { 672 new->e_argv[cnt] = *argv; 673 new->e_len[cnt] = 0; 674 } 675 } |
676 if (new->flags & F_EXECPLUS) { 677 new->e_psize = new->e_pbsize; 678 cnt--; 679 for (i = 0; i < new->e_pnummax; i++) { 680 new->e_argv[cnt] = NULL; 681 new->e_len[cnt] = 0; 682 cnt++; 683 } 684 argv = ap; 685 goto done; 686 } |
687 new->e_argv[cnt] = new->e_orig[cnt] = NULL; 688 |
689done: *argvp = argv + 1; |
690 return new; 691} 692 693int 694f_flags(plan, entry) 695 PLAN *plan; 696 FTSENT *entry; 697{ --- 909 unchanged lines hidden --- |