xref: /386bsd/usr/src/usr.bin/find/option.c (revision a2142627)
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * 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 
37 #ifndef lint
38 static char sccsid[] = "@(#)option.c	5.8 (Berkeley) 6/4/91";
39 #endif /* not lint */
40 
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <fts.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include "find.h"
48 
49 typedef struct _option {
50 	char *name;		/* option name */
51 	enum ntype token;	/* token type */
52 	PLAN *(*create)();	/* create function */
53 #define	O_NONE		0x01	/* no call required */
54 #define	O_ZERO		0x02	/* pass: nothing */
55 #define	O_ARGV		0x04	/* pass: argv, increment argv */
56 #define	O_ARGVP		0x08	/* pass: *argv, N_OK || N_EXEC */
57 	int flags;
58 } OPTION;
59 
60 OPTION options[] = {
61 	"!",		N_NOT,		c_not,		O_ZERO,
62 	"(",		N_OPENPAREN,	c_openparen,	O_ZERO,
63 	")",		N_CLOSEPAREN,	c_closeparen,	O_ZERO,
64 	"-a",		N_AND,		NULL,		O_NONE,
65 	"-and",		N_AND,		NULL,		O_NONE,
66 	"-atime",	N_ATIME,	c_atime,	O_ARGV,
67 	"-ctime",	N_CTIME,	c_ctime,	O_ARGV,
68 	"-depth",	N_DEPTH,	c_depth,	O_ZERO,
69 	"-exec",	N_EXEC,		c_exec,		O_ARGVP,
70 	"-follow",	N_FOLLOW,	c_follow,	O_ZERO,
71 	"-fstype",	N_FSTYPE,	c_fstype,	O_ARGV,
72 	"-group",	N_GROUP,	c_group,	O_ARGV,
73 	"-inum",	N_INUM,		c_inum,		O_ARGV,
74 	"-links",	N_LINKS,	c_links,	O_ARGV,
75 	"-ls",		N_LS,		c_ls,		O_ZERO,
76 	"-mtime",	N_MTIME,	c_mtime,	O_ARGV,
77 	"-name",	N_NAME,		c_name,		O_ARGV,
78 	"-newer",	N_NEWER,	c_newer,	O_ARGV,
79 	"-nogroup",	N_NOGROUP,	c_nogroup,	O_ZERO,
80 	"-nouser",	N_NOUSER,	c_nouser,	O_ZERO,
81 	"-o",		N_OR,		c_or,		O_ZERO,
82 	"-ok",		N_OK,		c_exec,		O_ARGVP,
83 	"-or",		N_OR,		c_or,		O_ZERO,
84 	"-perm",	N_PERM,		c_perm,		O_ARGV,
85 	"-print",	N_PRINT,	c_print,	O_ZERO,
86 	"-prune",	N_PRUNE,	c_prune,	O_ZERO,
87 	"-size",	N_SIZE,		c_size,		O_ARGV,
88 	"-type",	N_TYPE,		c_type,		O_ARGV,
89 	"-user",	N_USER,		c_user,		O_ARGV,
90 	"-xdev",	N_XDEV,		c_xdev,		O_ZERO,
91 	{ NULL },
92 };
93 
94 /*
95  * find_create --
96  *	create a node corresponding to a command line argument.
97  *
98  * TODO:
99  *	add create/process function pointers to node, so we can skip
100  *	this switch stuff.
101  */
102 PLAN *
find_create(argvp)103 find_create(argvp)
104 	char ***argvp;
105 {
106 	register OPTION *p;
107 	PLAN *new;
108 	char **argv;
109 	OPTION *option();
110 
111 	argv = *argvp;
112 
113 	if ((p = option(*argv)) == NULL) {
114 		(void)fprintf(stderr, "find: unknown option %s.\n", *argv);
115 		exit(1);
116 	}
117 	++argv;
118 	if (p->flags & (O_ARGV|O_ARGVP) && !*argv) {
119 		(void)fprintf(stderr,
120 		    "find: %s requires additional arguments.\n", *--argv);
121 		exit(1);
122 	}
123 
124 	switch(p->flags) {
125 	case O_NONE:
126 		new = NULL;
127 		break;
128 	case O_ZERO:
129 		new = (p->create)();
130 		break;
131 	case O_ARGV:
132 		new = (p->create)(*argv++);
133 		break;
134 	case O_ARGVP:
135 		new = (p->create)(&argv, p->token == N_OK);
136 		break;
137 	}
138 	*argvp = argv;
139 	return(new);
140 }
141 
142 OPTION *
option(name)143 option(name)
144 	char *name;
145 {
146 	OPTION tmp;
147 	int typecompare __P((const void *, const void *));
148 
149 	tmp.name = name;
150 	return((OPTION *)bsearch(&tmp, options,
151 	    sizeof(options)/sizeof(OPTION), sizeof(OPTION), typecompare));
152 }
153 
typecompare(a,b)154 typecompare(a, b)
155 	const void *a, *b;
156 {
157 	return(strcmp(((OPTION *)a)->name, ((OPTION *)b)->name));
158 }
159