Remove __P macros from src/usr.bin and src/usr.sbin.
[dragonfly.git] / usr.bin / find / option.c
1 /*-
2  * Copyright (c) 1990, 1993, 1994
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
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * @(#)option.c 8.2 (Berkeley) 4/16/94
37  * $FreeBSD: src/usr.bin/find/option.c,v 1.9.2.6 2003/02/22 16:33:24 des Exp $
38  * $DragonFly: src/usr.bin/find/option.c,v 1.4 2003/11/03 19:31:29 eirikn Exp $
39  */
40
41 #include <sys/types.h>
42 #include <sys/stat.h>
43
44 #include <err.h>
45 #include <fts.h>
46 #include <regex.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50
51 #include "find.h"
52
53 /* NB: the following table must be sorted lexically. */
54 static OPTION const options[] = {
55         { "!",          c_simple,       f_not,          0 },
56         { "(",          c_simple,       f_openparen,    0 },
57         { ")",          c_simple,       f_closeparen,   0 },
58         { "-a",         c_and,          NULL,           0 },
59         { "-amin",      c_Xmin,         f_Xmin,         F_TIME_A },
60         { "-and",       c_and,          NULL,           0 },
61         { "-anewer",    c_newer,        f_newer,        F_TIME_A },
62         { "-atime",     c_Xtime,        f_Xtime,        F_TIME_A },
63         { "-cmin",      c_Xmin,         f_Xmin,         F_TIME_C },
64         { "-cnewer",    c_newer,        f_newer,        F_TIME_C },
65         { "-ctime",     c_Xtime,        f_Xtime,        F_TIME_C },
66         { "-delete",    c_delete,       f_delete,       0 },
67         { "-depth",     c_depth,        f_always_true,  0 },
68         { "-empty",     c_empty,        f_empty,        0 },
69         { "-exec",      c_exec,         f_exec,         0 },
70         { "-execdir",   c_exec,         f_exec,         F_EXECDIR },
71         { "-false",     c_simple,       f_not,          0 },
72         { "-flags",     c_flags,        f_flags,        0 },
73         { "-follow",    c_follow,       f_always_true,  0 },
74 /*
75  * NetBSD doesn't provide a getvfsbyname(), so this option
76  * is not available if using a NetBSD kernel.
77  */
78 #if !defined(__NetBSD__)
79         { "-fstype",    c_fstype,       f_fstype,       0 },
80 #endif
81         { "-group",     c_group,        f_group,        0 },
82         { "-iname",     c_name,         f_name,         F_IGNCASE },
83         { "-inum",      c_inum,         f_inum,         0 },
84         { "-ipath",     c_name,         f_path,         F_IGNCASE },
85         { "-iregex",    c_regex,        f_regex,        F_IGNCASE },
86         { "-links",     c_links,        f_links,        0 },
87         { "-ls",        c_ls,           f_ls,           0 },
88         { "-maxdepth",  c_mXXdepth,     f_always_true,  F_MAXDEPTH },
89         { "-mindepth",  c_mXXdepth,     f_always_true,  0 },
90         { "-mmin",      c_Xmin,         f_Xmin,         0 },
91         { "-mnewer",    c_newer,        f_newer,        0 },
92         { "-mtime",     c_Xtime,        f_Xtime,        0 },
93         { "-name",      c_name,         f_name,         0 },
94         { "-newer",     c_newer,        f_newer,        0 },
95         { "-neweraa",   c_newer,        f_newer,        F_TIME_A | F_TIME2_A },
96         { "-newerac",   c_newer,        f_newer,        F_TIME_A | F_TIME2_C },
97         { "-neweram",   c_newer,        f_newer,        F_TIME_A },
98         { "-newerat",   c_newer,        f_newer,        F_TIME_A | F_TIME2_T },
99         { "-newerca",   c_newer,        f_newer,        F_TIME_C | F_TIME2_A },
100         { "-newercc",   c_newer,        f_newer,        F_TIME_C | F_TIME2_C },
101         { "-newercm",   c_newer,        f_newer,        F_TIME_C },
102         { "-newerct",   c_newer,        f_newer,        F_TIME_C | F_TIME2_T },
103         { "-newerma",   c_newer,        f_newer,        F_TIME2_A },
104         { "-newermc",   c_newer,        f_newer,        F_TIME2_C },
105         { "-newermm",   c_newer,        f_newer,        0 },
106         { "-newermt",   c_newer,        f_newer,        F_TIME2_T },
107         { "-nogroup",   c_nogroup,      f_nogroup,      0 },
108         { "-not",       c_simple,       f_not,          0 },
109         { "-nouser",    c_nouser,       f_nouser,       0 },
110         { "-o",         c_simple,       f_or,           0 },
111         { "-ok",        c_exec,         f_exec,         F_NEEDOK },
112         { "-okdir",     c_exec,         f_exec,         F_NEEDOK | F_EXECDIR },
113         { "-or",        c_simple,       f_or,           0 },
114         { "-path",      c_name,         f_path,         0 },
115         { "-perm",      c_perm,         f_perm,         0 },
116         { "-print",     c_print,        f_print,        0 },
117         { "-print0",    c_print,        f_print0,       0 },
118         { "-prune",     c_simple,       f_prune,        0 },
119         { "-regex",     c_regex,        f_regex,        0 },
120         { "-size",      c_size,         f_size,         0 },
121         { "-type",      c_type,         f_type,         0 },
122         { "-user",      c_user,         f_user,         0 },
123         { "-xdev",      c_xdev,         f_always_true,  0 },
124 };
125
126 /*
127  * find_create --
128  *      create a node corresponding to a command line argument.
129  *
130  * TODO:
131  *      add create/process function pointers to node, so we can skip
132  *      this switch stuff.
133  */
134 PLAN *
135 find_create(char ***argvp)
136 {
137         register OPTION *p;
138         PLAN *new;
139         char **argv;
140
141         argv = *argvp;
142
143         if ((p = option(*argv)) == NULL)
144                 errx(1, "%s: unknown option", *argv);
145         ++argv;
146
147         new = (p->create)(p, &argv);
148         *argvp = argv;
149         return (new);
150 }
151
152 OPTION *
153 option(char *name)
154 {
155         OPTION tmp;
156         int typecompare(const void *, const void *);
157
158         tmp.name = name;
159         return ((OPTION *)bsearch(&tmp, options,
160             sizeof(options)/sizeof(OPTION), sizeof(OPTION), typecompare));
161 }
162
163 int
164 typecompare(const void *a, const void *b)
165 {
166         return (strcmp(((OPTION *)a)->name, ((OPTION *)b)->name));
167 }