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);
|