Commit | Line | Data |
---|---|---|
45fc66f9 KB |
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 | * %sccs.include.redist.c% | |
9 | */ | |
10 | ||
11 | #ifndef lint | |
b1a11722 | 12 | static char sccsid[] = "@(#)option.c 5.3 (Berkeley) %G%"; |
45fc66f9 KB |
13 | #endif /* not lint */ |
14 | ||
15 | #include <sys/types.h> | |
16 | #include <sys/stat.h> | |
17 | #include <fts.h> | |
18 | #include <stdio.h> | |
19 | #include "find.h" | |
20 | ||
21 | typedef struct _option { | |
22 | char *name; /* option name */ | |
23 | int token; /* token value */ | |
24 | PLAN *(*create)(); /* create function */ | |
25 | #define O_NONE 0x01 /* no call required */ | |
26 | #define O_ZERO 0x02 /* pass: nothing */ | |
27 | #define O_ARGV 0x04 /* pass: argv, increment argv */ | |
28 | #define O_ARGVP 0x08 /* pass: *argv, T_OK || T_EXEC */ | |
202dd4ce KB |
29 | #define O_MASK 0x0f /* mask of op bits */ |
30 | #define O_OLD 0x10 /* deprecated syntax */ | |
31 | #define O_NEW 0x20 /* new syntax */ | |
45fc66f9 KB |
32 | int flags; |
33 | } OPTION; | |
34 | ||
35 | PLAN *c_atime(), *c_ctime(), *c_depth(), *c_exec(), *c_follow(), | |
36 | *c_fstype(), *c_group(), *c_inum(), *c_links(), *c_ls(), | |
37 | *c_mtime(), *c_name(), *c_newer(), *c_nogroup(), *c_nouser(), | |
202dd4ce | 38 | *c_perm(), *c_print(), *c_prune(), *c_size(), *c_type(), |
45fc66f9 KB |
39 | *c_user(), *c_xdev(), *c_openparen(), *c_closeparen(), *c_not(), |
40 | *c_or(); | |
41 | ||
42 | OPTION options[] = { | |
43 | "!", T_NOT, c_not, O_ZERO, | |
44 | "(", T_OPENPAREN, c_openparen, O_ZERO, | |
45 | ")", T_CLOSEPAREN, c_closeparen, O_ZERO, | |
b1a11722 KB |
46 | "a", T_AND, NULL, O_NONE|O_OLD, |
47 | "and", T_AND, NULL, O_NONE|O_NEW, | |
202dd4ce KB |
48 | "atime", T_ATIME, c_atime, O_ARGV, |
49 | "ctime", T_CTIME, c_ctime, O_ARGV, | |
50 | "depth", T_DEPTH, c_depth, O_ZERO|O_OLD, | |
51 | "exec", T_EXEC, c_exec, O_ARGVP, | |
52 | "follow", T_FOLLOW, c_follow, O_ZERO|O_OLD, | |
53 | "fstype", T_FSTYPE, c_fstype, O_ARGV, | |
54 | "group", T_GROUP, c_group, O_ARGV, | |
55 | "inum", T_INUM, c_inum, O_ARGV, | |
56 | "links", T_LINKS, c_links, O_ARGV, | |
57 | "ls", T_LS, c_ls, O_ZERO, | |
58 | "mtime", T_MTIME, c_mtime, O_ARGV, | |
59 | "name", T_NAME, c_name, O_ARGV, | |
60 | "newer", T_NEWER, c_newer, O_ARGV, | |
61 | "nogroup", T_NOGROUP, c_nogroup, O_ZERO, | |
62 | "nouser", T_NOUSER, c_nouser, O_ZERO, | |
63 | "o", T_OR, c_or, O_ZERO|O_OLD, | |
64 | "ok", T_OK, c_exec, O_ARGVP, | |
65 | "or", T_OR, c_or, O_ZERO|O_NEW, | |
66 | "perm", T_PERM, c_perm, O_ARGV, | |
67 | "print", T_PRINT, c_print, O_ZERO, | |
68 | "prune", T_PRUNE, c_prune, O_ZERO, | |
69 | "size", T_SIZE, c_size, O_ARGV, | |
70 | "type", T_TYPE, c_type, O_ARGV, | |
71 | "user", T_USER, c_user, O_ARGV, | |
72 | "xdev", T_XDEV, c_xdev, O_ZERO|O_OLD, | |
45fc66f9 KB |
73 | { NULL }, |
74 | }; | |
75 | ||
76 | /* | |
77 | * find_create -- | |
78 | * create a node corresponding to a command line argument. | |
79 | * | |
80 | * TODO: | |
81 | * add create/process function pointers to node, so we can skip | |
82 | * this switch stuff. | |
83 | */ | |
84 | PLAN * | |
85 | find_create(argvp) | |
86 | char ***argvp; | |
87 | { | |
202dd4ce | 88 | extern int deprecated; |
45fc66f9 KB |
89 | register OPTION *p; |
90 | OPTION tmp; | |
91 | PLAN *new; | |
92 | char **argv; | |
45fc66f9 KB |
93 | int typecompare(); |
94 | ||
95 | argv = *argvp; | |
96 | tmp.name = *argv++; | |
97 | ||
202dd4ce KB |
98 | /* strip off any leading dash */ |
99 | if (*tmp.name == '-') | |
100 | ++tmp.name; | |
101 | ||
45fc66f9 KB |
102 | p = (OPTION *)bsearch(&tmp, options, sizeof(options)/sizeof(OPTION), |
103 | sizeof(OPTION), typecompare); | |
202dd4ce KB |
104 | if (!p || deprecated && p->flags&O_NEW || |
105 | !deprecated && p->flags&O_OLD) { | |
45fc66f9 KB |
106 | (void)fprintf(stderr, "find: unknown option %s.\n", *--argv); |
107 | exit(1); | |
108 | } | |
109 | if (p->flags & (O_ARGV|O_ARGVP) && !*argv) { | |
110 | (void)fprintf(stderr, | |
111 | "find: %s requires additional arguments.\n", *--argv); | |
112 | exit(1); | |
113 | } | |
114 | ||
202dd4ce | 115 | switch(p->flags&O_MASK) { |
b1a11722 KB |
116 | case O_NONE: |
117 | new = NULL; | |
118 | break; | |
45fc66f9 KB |
119 | case O_ZERO: |
120 | new = (p->create)(); | |
121 | break; | |
122 | case O_ARGV: | |
123 | new = (p->create)(*argv++); | |
124 | break; | |
125 | case O_ARGVP: | |
126 | new = (p->create)(&argv, p->token == T_OK); | |
127 | break; | |
128 | } | |
129 | *argvp = argv; | |
130 | return(new); | |
131 | } | |
132 | ||
133 | typecompare(a, b) | |
134 | OPTION *a, *b; | |
135 | { | |
136 | return(strcmp(a->name, b->name)); | |
137 | } |