]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/find/option.c
MFV r329760: 7638 Refactor spa_load_impl into several functions
[FreeBSD/FreeBSD.git] / usr.bin / find / option.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1990, 1993, 1994
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Cimarron D. Taylor of the University of California, Berkeley.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 #ifndef lint
36 /*
37 static char sccsid[] = "@(#)option.c    8.2 (Berkeley) 4/16/94";
38 */
39 #endif /* not lint */
40
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #include <sys/types.h>
45 #include <sys/stat.h>
46
47 #include <err.h>
48 #include <fts.h>
49 #include <regex.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53
54 #include "find.h"
55
56 static int typecompare(const void *, const void *);
57
58 /* NB: the following table must be sorted lexically. */
59 /* Options listed with C++ comments are in gnu find, but not our find */
60 static OPTION const options[] = {
61         { "!",          c_simple,       f_not,          0 },
62         { "(",          c_simple,       f_openparen,    0 },
63         { ")",          c_simple,       f_closeparen,   0 },
64 #if HAVE_STRUCT_STAT_ST_BIRTHTIME
65         { "-Bmin",      c_Xmin,         f_Xmin,         F_TIME_B },
66         { "-Bnewer",    c_newer,        f_newer,        F_TIME_B },
67         { "-Btime",     c_Xtime,        f_Xtime,        F_TIME_B },
68 #endif
69         { "-a",         c_and,          NULL,           0 },
70 #ifdef ACL_TYPE_NFS4
71         { "-acl",       c_acl,          f_acl,          0 },
72 #endif
73         { "-amin",      c_Xmin,         f_Xmin,         F_TIME_A },
74         { "-and",       c_and,          NULL,           0 },
75         { "-anewer",    c_newer,        f_newer,        F_TIME_A },
76         { "-atime",     c_Xtime,        f_Xtime,        F_TIME_A },
77         { "-cmin",      c_Xmin,         f_Xmin,         F_TIME_C },
78         { "-cnewer",    c_newer,        f_newer,        F_TIME_C },
79         { "-ctime",     c_Xtime,        f_Xtime,        F_TIME_C },
80         { "-d",         c_depth,        f_depth,        0 },
81 // -daystart
82         { "-delete",    c_delete,       f_delete,       0 },
83         { "-depth",     c_depth,        f_depth,        0 },
84         { "-empty",     c_empty,        f_empty,        0 },
85         { "-exec",      c_exec,         f_exec,         0 },
86         { "-execdir",   c_exec,         f_exec,         F_EXECDIR },
87         { "-false",     c_simple,       f_false,        0 },
88 #if HAVE_STRUCT_STAT_ST_FLAGS
89         { "-flags",     c_flags,        f_flags,        0 },
90 #endif
91 // -fls
92         { "-follow",    c_follow,       f_always_true,  0 },
93 // -fprint
94 // -fprint0
95 // -fprintf
96 #if HAVE_STRUCT_STATFS_F_FSTYPENAME
97         { "-fstype",    c_fstype,       f_fstype,       0 },
98 #endif
99         { "-gid",       c_group,        f_group,        0 },
100         { "-group",     c_group,        f_group,        0 },
101         { "-ignore_readdir_race",c_ignore_readdir_race, f_always_true,0 },
102         { "-ilname",    c_name,         f_name,         F_LINK | F_IGNCASE },
103         { "-iname",     c_name,         f_name,         F_IGNCASE },
104         { "-inum",      c_inum,         f_inum,         0 },
105         { "-ipath",     c_name,         f_path,         F_IGNCASE },
106         { "-iregex",    c_regex,        f_regex,        F_IGNCASE },
107         { "-iwholename",c_name,         f_path,         F_IGNCASE },
108         { "-links",     c_links,        f_links,        0 },
109         { "-lname",     c_name,         f_name,         F_LINK },
110         { "-ls",        c_ls,           f_ls,           0 },
111         { "-maxdepth",  c_mXXdepth,     f_always_true,  F_MAXDEPTH },
112         { "-mindepth",  c_mXXdepth,     f_always_true,  0 },
113         { "-mmin",      c_Xmin,         f_Xmin,         0 },
114         { "-mnewer",    c_newer,        f_newer,        0 },
115         { "-mount",     c_xdev,         f_always_true,  0 },
116         { "-mtime",     c_Xtime,        f_Xtime,        0 },
117         { "-name",      c_name,         f_name,         0 },
118         { "-newer",     c_newer,        f_newer,        0 },
119 #if HAVE_STRUCT_STAT_ST_BIRTHTIME
120         { "-newerBB",   c_newer,        f_newer,        F_TIME_B | F_TIME2_B },
121         { "-newerBa",   c_newer,        f_newer,        F_TIME_B | F_TIME2_A },
122         { "-newerBc",   c_newer,        f_newer,        F_TIME_B | F_TIME2_C },
123         { "-newerBm",   c_newer,        f_newer,        F_TIME_B },
124         { "-newerBt",   c_newer,        f_newer,        F_TIME_B | F_TIME2_T },
125         { "-neweraB",   c_newer,        f_newer,        F_TIME_A | F_TIME2_B },
126 #endif
127         { "-neweraa",   c_newer,        f_newer,        F_TIME_A | F_TIME2_A },
128         { "-newerac",   c_newer,        f_newer,        F_TIME_A | F_TIME2_C },
129         { "-neweram",   c_newer,        f_newer,        F_TIME_A },
130         { "-newerat",   c_newer,        f_newer,        F_TIME_A | F_TIME2_T },
131 #if HAVE_STRUCT_STAT_ST_BIRTHTIME
132         { "-newercB",   c_newer,        f_newer,        F_TIME_C | F_TIME2_B },
133 #endif
134         { "-newerca",   c_newer,        f_newer,        F_TIME_C | F_TIME2_A },
135         { "-newercc",   c_newer,        f_newer,        F_TIME_C | F_TIME2_C },
136         { "-newercm",   c_newer,        f_newer,        F_TIME_C },
137         { "-newerct",   c_newer,        f_newer,        F_TIME_C | F_TIME2_T },
138 #if HAVE_STRUCT_STAT_ST_BIRTHTIME
139         { "-newermB",   c_newer,        f_newer,        F_TIME2_B },
140 #endif
141         { "-newerma",   c_newer,        f_newer,        F_TIME2_A },
142         { "-newermc",   c_newer,        f_newer,        F_TIME2_C },
143         { "-newermm",   c_newer,        f_newer,        0 },
144         { "-newermt",   c_newer,        f_newer,        F_TIME2_T },
145         { "-nogroup",   c_nogroup,      f_nogroup,      0 },
146         { "-noignore_readdir_race",c_ignore_readdir_race, f_always_true,0 },
147         { "-noleaf",    c_simple,       f_always_true,  0 },
148         { "-not",       c_simple,       f_not,          0 },
149         { "-nouser",    c_nouser,       f_nouser,       0 },
150         { "-o",         c_simple,       f_or,           0 },
151         { "-ok",        c_exec,         f_exec,         F_NEEDOK },
152         { "-okdir",     c_exec,         f_exec,         F_NEEDOK | F_EXECDIR },
153         { "-or",        c_simple,       f_or,           0 },
154         { "-path",      c_name,         f_path,         0 },
155         { "-perm",      c_perm,         f_perm,         0 },
156         { "-print",     c_print,        f_print,        0 },
157         { "-print0",    c_print,        f_print0,       0 },
158 // -printf
159         { "-prune",     c_simple,       f_prune,        0 },
160         { "-quit",      c_simple,       f_quit,         0 },
161         { "-regex",     c_regex,        f_regex,        0 },
162         { "-samefile",  c_samefile,     f_inum,         0 },
163         { "-size",      c_size,         f_size,         0 },
164         { "-sparse",    c_sparse,       f_sparse,       0 },
165         { "-true",      c_simple,       f_always_true,  0 },
166         { "-type",      c_type,         f_type,         0 },
167         { "-uid",       c_user,         f_user,         0 },
168         { "-user",      c_user,         f_user,         0 },
169         { "-wholename", c_name,         f_path,         0 },
170         { "-xdev",      c_xdev,         f_always_true,  0 },
171 // -xtype
172 };
173
174 /*
175  * find_create --
176  *      create a node corresponding to a command line argument.
177  *
178  * TODO:
179  *      add create/process function pointers to node, so we can skip
180  *      this switch stuff.
181  */
182 PLAN *
183 find_create(char ***argvp)
184 {
185         OPTION *p;
186         PLAN *new;
187         char **argv;
188
189         argv = *argvp;
190
191         if ((p = lookup_option(*argv)) == NULL)
192                 errx(1, "%s: unknown primary or operator", *argv);
193         ++argv;
194
195         new = (p->create)(p, &argv);
196         *argvp = argv;
197         return (new);
198 }
199
200 OPTION *
201 lookup_option(const char *name)
202 {
203         OPTION tmp;
204
205         tmp.name = name;
206         return ((OPTION *)bsearch(&tmp, options,
207             sizeof(options)/sizeof(OPTION), sizeof(OPTION), typecompare));
208 }
209
210 static int
211 typecompare(const void *a, const void *b)
212 {
213         return (strcmp(((const OPTION *)a)->name, ((const OPTION *)b)->name));
214 }