Print this page
3795 find does not support -path or -ipath


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.

  24  */
  25 
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 
  31 /*      Parts of this product may be derived from               */
  32 /*      Mortice Kern Systems Inc. and Berkeley 4.3 BSD systems. */
  33 /*      licensed from  Mortice Kern Systems Inc. and            */
  34 /*      the University of California.                           */
  35 
  36 /*
  37  * Copyright 1985, 1990 by Mortice Kern Systems Inc.  All rights reserved.
  38  */
  39 
  40 #include <stdio.h>
  41 #include <errno.h>
  42 #include <pwd.h>
  43 #include <grp.h>


  66 #define BLKSIZ          512
  67 #define round(x, s)     (((x)+(s)-1)&~((s)-1))
  68 #ifndef FTW_SLN
  69 #define FTW_SLN         7
  70 #endif
  71 #define LINEBUF_SIZE            LINE_MAX        /* input or output lines */
  72 #define REMOTE_FS               "/etc/dfs/fstypes"
  73 #define N_FSTYPES               20
  74 #define SHELL_MAXARGS           253     /* see doexec() for description */
  75 
  76 /*
  77  * This is the list of operations
  78  * F_USER and F_GROUP are named to avoid conflict with USER and GROUP defined
  79  * in sys/acl.h
  80  */
  81 
  82 enum Command
  83 {
  84         PRINT,
  85         ACL, AMIN, AND, ATIME, CMIN, CPIO, CSIZE, CTIME, DEPTH, EXEC, F_GROUP,
  86         F_GROUPACL, F_USER, F_USERACL, FOLLOW, FSTYPE, INAME, INUM, IREGEX,
  87         LINKS, LOCAL, LPAREN, LS, MAXDEPTH, MINDEPTH, MMIN, MOUNT, MTIME, NAME,
  88         NCPIO, NEWER, NOGRP, NOT, NOUSER, OK, OR, PERM, PRINT0, PRUNE, REGEX,
  89         RPAREN, SIZE, TYPE, VARARGS, XATTR
  90 };
  91 
  92 enum Type
  93 {
  94         Unary, Id, Num, Str, Exec, Cpio, Op
  95 };
  96 
  97 struct Args
  98 {
  99         char            name[10];
 100         enum Command    action;
 101         enum Type       type;
 102 };
 103 
 104 /*
 105  * Except for pathnames, these are the only legal arguments
 106  */
 107 static struct Args commands[] =
 108 {
 109         "!",            NOT,            Op,
 110         "(",            LPAREN,         Unary,
 111         ")",            RPAREN,         Unary,
 112         "-a",           AND,            Op,
 113         "-acl",         ACL,            Unary,
 114         "-amin",        AMIN,           Num,
 115         "-and",         AND,            Op,
 116         "-atime",       ATIME,          Num,
 117         "-cmin",        CMIN,           Num,
 118         "-cpio",        CPIO,           Cpio,
 119         "-ctime",       CTIME,          Num,
 120         "-depth",       DEPTH,          Unary,
 121         "-exec",        EXEC,           Exec,
 122         "-follow",      FOLLOW,         Unary,
 123         "-fstype",      FSTYPE,         Str,
 124         "-group",       F_GROUP,        Num,
 125         "-groupacl",    F_GROUPACL,     Num,
 126         "-iname",       INAME,          Str,
 127         "-inum",        INUM,           Num,

 128         "-iregex",      IREGEX,         Str,
 129         "-links",       LINKS,          Num,
 130         "-local",       LOCAL,          Unary,
 131         "-ls",          LS,             Unary,
 132         "-maxdepth",    MAXDEPTH,       Num,
 133         "-mindepth",    MINDEPTH,       Num,
 134         "-mmin",        MMIN,           Num,
 135         "-mount",       MOUNT,          Unary,
 136         "-mtime",       MTIME,          Num,
 137         "-name",        NAME,           Str,
 138         "-ncpio",       NCPIO,          Cpio,
 139         "-newer",       NEWER,          Str,
 140         "-nogroup",     NOGRP,          Unary,
 141         "-not",         NOT,            Op,
 142         "-nouser",      NOUSER,         Unary,
 143         "-o",           OR,             Op,
 144         "-ok",          OK,             Exec,
 145         "-or",          OR,             Op,

 146         "-perm",        PERM,           Num,
 147         "-print",       PRINT,          Unary,
 148         "-print0",      PRINT0,         Unary,
 149         "-prune",       PRUNE,          Unary,
 150         "-regex",       REGEX,          Str,
 151         "-size",        SIZE,           Num,
 152         "-type",        TYPE,           Num,
 153         "-user",        F_USER,         Num,
 154         "-useracl",     F_USERACL,      Num,
 155         "-xattr",       XATTR,          Unary,
 156         "-xdev",        MOUNT,          Unary,
 157         NULL,           0,              0
 158 };
 159 
 160 union Item
 161 {
 162         struct Node     *np;
 163         struct Arglist  *vp;
 164         time_t          t;
 165         char            *cp;


 604                                 }
 605                                 if (strcmp(b, ";") == 0) {
 606                                         *av = 0;
 607                                         break;
 608                                 } else if (strcmp(b, "{}") == 0)
 609                                         *av = dummyarg;
 610                                 else if (strcmp(b, "+") == 0 &&
 611                                         av[-1] == dummyarg &&
 612                                         np->action == EXEC) {
 613                                         av[-1] = 0;
 614                                         np->first.vp = varargs(np->first.ap);
 615                                         np->action = VARARGS;
 616                                         break;
 617                                 }
 618                                 av++;
 619                         }
 620                         break;
 621 
 622                 case NAME:
 623                 case INAME:


 624                         np->first.cp = b;
 625                         break;
 626                 case REGEX:
 627                 case IREGEX: {
 628                         int error;
 629                         size_t errlen;
 630                         char *errmsg;
 631 
 632                         if ((preg = realloc(preg, (npreg + 1) *
 633                             sizeof (regex_t))) == NULL)
 634                                 err(1, "realloc");
 635                         if ((error = regcomp(&preg[npreg], b,
 636                             ((np->action == IREGEX) ? REG_ICASE : 0) |
 637                             ((Eflag) ? REG_EXTENDED : 0))) != 0) {
 638                                 errlen = regerror(error, &preg[npreg], NULL, 0);
 639                                 if ((errmsg = malloc(errlen)) == NULL)
 640                                         err(1, "malloc");
 641                                 (void) regerror(error, &preg[npreg], errmsg,
 642                                     errlen);
 643                                 errx(1, gettext("RE error: %s"), errmsg);


 976                         } else {
 977                                 /* no more room, exec command */
 978                                 *ap->nextvar++ = name;
 979                                 *ap->nextvar = 0;
 980                                 val = 1;
 981                                 (void) doexec((char *)0, ap->arglist,
 982                                     &exec_exitcode);
 983                                 ap->nextstr = ap->end;
 984                                 ap->nextvar = ap->firstvar;
 985                         }
 986                         break;
 987                 }
 988 
 989                 case DEPTH:
 990                 case MOUNT:
 991                 case FOLLOW:
 992                         val = 1;
 993                         break;
 994 
 995                 case NAME:
 996                 case INAME: {
 997                         char *name1;
 998                         int fnmflags = (np->action == INAME) ?
 999                             FNM_IGNORECASE : 0;




1000 
1001                         /*
1002                          * basename(3c) may modify name, so
1003                          * we need to pass another string
1004                          */
1005                         if ((name1 = strdup(name)) == NULL) {
1006                                 (void) fprintf(stderr,
1007                                     gettext("%s: cannot strdup() %s: %s\n"),
1008                                     cmdname, name, strerror(errno));
1009                                 exit(2);
1010                         }
1011                         /*
1012                          * XPG4 find should not treat a leading '.' in a
1013                          * filename specially for pattern matching.
1014                          * /usr/bin/find  will not pattern match a leading
1015                          * '.' in a filename, unless '.' is explicitly
1016                          * specified.
1017                          */
1018 #ifndef XPG4
1019                         fnmflags |= FNM_PERIOD;
1020 #endif
1021                         val = !fnmatch(np->first.cp, basename(name1), fnmflags);
1022                         free(name1);



1023                         break;
1024                 }
1025 
1026                 case PRUNE:
1027                         if (type == FTW_D)
1028                                 state->quit = FTW_PRUNE;
1029                         val = 1;
1030                         break;
1031                 case NOUSER:
1032                         val = ((getpwuid(statb->st_uid)) == 0);
1033                         break;
1034                 case NOGRP:
1035                         val = ((getgrgid(statb->st_gid)) == 0);
1036                         break;
1037                 case FSTYPE:
1038                         val = (strcmp(np->first.cp, statb->st_fstype) == 0);
1039                         break;
1040                 case CPIO:
1041                         output = (FILE *)np->first.l;
1042                         (void) fprintf(output, "%s\n", name);




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  24  * Copyright (c) 2013 Andrew Stormont.  All rights reserved.
  25  */
  26 
  27 
  28 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  29 /*        All Rights Reserved   */
  30 
  31 
  32 /*      Parts of this product may be derived from               */
  33 /*      Mortice Kern Systems Inc. and Berkeley 4.3 BSD systems. */
  34 /*      licensed from  Mortice Kern Systems Inc. and            */
  35 /*      the University of California.                           */
  36 
  37 /*
  38  * Copyright 1985, 1990 by Mortice Kern Systems Inc.  All rights reserved.
  39  */
  40 
  41 #include <stdio.h>
  42 #include <errno.h>
  43 #include <pwd.h>
  44 #include <grp.h>


  67 #define BLKSIZ          512
  68 #define round(x, s)     (((x)+(s)-1)&~((s)-1))
  69 #ifndef FTW_SLN
  70 #define FTW_SLN         7
  71 #endif
  72 #define LINEBUF_SIZE            LINE_MAX        /* input or output lines */
  73 #define REMOTE_FS               "/etc/dfs/fstypes"
  74 #define N_FSTYPES               20
  75 #define SHELL_MAXARGS           253     /* see doexec() for description */
  76 
  77 /*
  78  * This is the list of operations
  79  * F_USER and F_GROUP are named to avoid conflict with USER and GROUP defined
  80  * in sys/acl.h
  81  */
  82 
  83 enum Command
  84 {
  85         PRINT,
  86         ACL, AMIN, AND, ATIME, CMIN, CPIO, CSIZE, CTIME, DEPTH, EXEC, F_GROUP,
  87         F_GROUPACL, F_USER, F_USERACL, FOLLOW, FSTYPE, INAME, INUM, IPATH,
  88         IREGEX, LINKS, LOCAL, LPAREN, LS, MAXDEPTH, MINDEPTH, MMIN, MOUNT,
  89         MTIME, NAME, NCPIO, NEWER, NOGRP, NOT, NOUSER, OK, OR, PATH, PERM,
  90         PRINT0, PRUNE, REGEX, RPAREN, SIZE, TYPE, VARARGS, XATTR
  91 };
  92 
  93 enum Type
  94 {
  95         Unary, Id, Num, Str, Exec, Cpio, Op
  96 };
  97 
  98 struct Args
  99 {
 100         char            name[10];
 101         enum Command    action;
 102         enum Type       type;
 103 };
 104 
 105 /*
 106  * Except for pathnames, these are the only legal arguments
 107  */
 108 static struct Args commands[] =
 109 {
 110         "!",            NOT,            Op,
 111         "(",            LPAREN,         Unary,
 112         ")",            RPAREN,         Unary,
 113         "-a",           AND,            Op,
 114         "-acl",         ACL,            Unary,
 115         "-amin",        AMIN,           Num,
 116         "-and",         AND,            Op,
 117         "-atime",       ATIME,          Num,
 118         "-cmin",        CMIN,           Num,
 119         "-cpio",        CPIO,           Cpio,
 120         "-ctime",       CTIME,          Num,
 121         "-depth",       DEPTH,          Unary,
 122         "-exec",        EXEC,           Exec,
 123         "-follow",      FOLLOW,         Unary,
 124         "-fstype",      FSTYPE,         Str,
 125         "-group",       F_GROUP,        Num,
 126         "-groupacl",    F_GROUPACL,     Num,
 127         "-iname",       INAME,          Str,
 128         "-inum",        INUM,           Num,
 129         "-ipath",       IPATH,          Str,
 130         "-iregex",      IREGEX,         Str,
 131         "-links",       LINKS,          Num,
 132         "-local",       LOCAL,          Unary,
 133         "-ls",          LS,             Unary,
 134         "-maxdepth",    MAXDEPTH,       Num,
 135         "-mindepth",    MINDEPTH,       Num,
 136         "-mmin",        MMIN,           Num,
 137         "-mount",       MOUNT,          Unary,
 138         "-mtime",       MTIME,          Num,
 139         "-name",        NAME,           Str,
 140         "-ncpio",       NCPIO,          Cpio,
 141         "-newer",       NEWER,          Str,
 142         "-nogroup",     NOGRP,          Unary,
 143         "-not",         NOT,            Op,
 144         "-nouser",      NOUSER,         Unary,
 145         "-o",           OR,             Op,
 146         "-ok",          OK,             Exec,
 147         "-or",          OR,             Op,
 148         "-path",        PATH,           Str,
 149         "-perm",        PERM,           Num,
 150         "-print",       PRINT,          Unary,
 151         "-print0",      PRINT0,         Unary,
 152         "-prune",       PRUNE,          Unary,
 153         "-regex",       REGEX,          Str,
 154         "-size",        SIZE,           Num,
 155         "-type",        TYPE,           Num,
 156         "-user",        F_USER,         Num,
 157         "-useracl",     F_USERACL,      Num,
 158         "-xattr",       XATTR,          Unary,
 159         "-xdev",        MOUNT,          Unary,
 160         NULL,           0,              0
 161 };
 162 
 163 union Item
 164 {
 165         struct Node     *np;
 166         struct Arglist  *vp;
 167         time_t          t;
 168         char            *cp;


 607                                 }
 608                                 if (strcmp(b, ";") == 0) {
 609                                         *av = 0;
 610                                         break;
 611                                 } else if (strcmp(b, "{}") == 0)
 612                                         *av = dummyarg;
 613                                 else if (strcmp(b, "+") == 0 &&
 614                                         av[-1] == dummyarg &&
 615                                         np->action == EXEC) {
 616                                         av[-1] = 0;
 617                                         np->first.vp = varargs(np->first.ap);
 618                                         np->action = VARARGS;
 619                                         break;
 620                                 }
 621                                 av++;
 622                         }
 623                         break;
 624 
 625                 case NAME:
 626                 case INAME:
 627                 case PATH:
 628                 case IPATH:
 629                         np->first.cp = b;
 630                         break;
 631                 case REGEX:
 632                 case IREGEX: {
 633                         int error;
 634                         size_t errlen;
 635                         char *errmsg;
 636 
 637                         if ((preg = realloc(preg, (npreg + 1) *
 638                             sizeof (regex_t))) == NULL)
 639                                 err(1, "realloc");
 640                         if ((error = regcomp(&preg[npreg], b,
 641                             ((np->action == IREGEX) ? REG_ICASE : 0) |
 642                             ((Eflag) ? REG_EXTENDED : 0))) != 0) {
 643                                 errlen = regerror(error, &preg[npreg], NULL, 0);
 644                                 if ((errmsg = malloc(errlen)) == NULL)
 645                                         err(1, "malloc");
 646                                 (void) regerror(error, &preg[npreg], errmsg,
 647                                     errlen);
 648                                 errx(1, gettext("RE error: %s"), errmsg);


 981                         } else {
 982                                 /* no more room, exec command */
 983                                 *ap->nextvar++ = name;
 984                                 *ap->nextvar = 0;
 985                                 val = 1;
 986                                 (void) doexec((char *)0, ap->arglist,
 987                                     &exec_exitcode);
 988                                 ap->nextstr = ap->end;
 989                                 ap->nextvar = ap->firstvar;
 990                         }
 991                         break;
 992                 }
 993 
 994                 case DEPTH:
 995                 case MOUNT:
 996                 case FOLLOW:
 997                         val = 1;
 998                         break;
 999 
1000                 case NAME:
1001                 case INAME:
1002                 case PATH:
1003                 case IPATH: {
1004                         char *path;
1005                         int fnmflags = 0;
1006 
1007                         if (np->action == INAME || np->action == IPATH)
1008                                 fnmflags = FNM_IGNORECASE;
1009 
1010                         /*
1011                          * basename(3c) may modify name, so
1012                          * we need to pass another string
1013                          */
1014                         if ((path = strdup(name)) == NULL) {
1015                                 (void) fprintf(stderr,
1016                                     gettext("%s: cannot strdup() %s: %s\n"),
1017                                     cmdname, name, strerror(errno));
1018                                 exit(2);
1019                         }
1020                         /*
1021                          * XPG4 find should not treat a leading '.' in a
1022                          * filename specially for pattern matching.
1023                          * /usr/bin/find  will not pattern match a leading
1024                          * '.' in a filename, unless '.' is explicitly
1025                          * specified.
1026                          */
1027 #ifndef XPG4
1028                         fnmflags |= FNM_PERIOD;
1029 #endif
1030 
1031                         val = !fnmatch(np->first.cp,
1032                             (np->action == NAME || np->action == INAME)
1033                                 ? basename(path) : path, fnmflags);
1034                         free(path);
1035                         break;
1036                 }
1037 
1038                 case PRUNE:
1039                         if (type == FTW_D)
1040                                 state->quit = FTW_PRUNE;
1041                         val = 1;
1042                         break;
1043                 case NOUSER:
1044                         val = ((getpwuid(statb->st_uid)) == 0);
1045                         break;
1046                 case NOGRP:
1047                         val = ((getgrgid(statb->st_gid)) == 0);
1048                         break;
1049                 case FSTYPE:
1050                         val = (strcmp(np->first.cp, statb->st_fstype) == 0);
1051                         break;
1052                 case CPIO:
1053                         output = (FILE *)np->first.l;
1054                         (void) fprintf(output, "%s\n", name);