Mercurial > hg > toybox
annotate toys/pending/find.c @ 1234:c99c215b4604 draft
find: clarify and expand the help for find -type
author | Isaac Dunham <ibid.ag@gmail.com> |
---|---|
date | Sat, 29 Mar 2014 15:25:23 -0500 |
parents | b042cd34e564 |
children | 85f297591693 |
rev | line source |
---|---|
814 | 1 /* vi: set sw=4 ts=4: |
2 * | |
3 * find.c - find files matching a criteria | |
4 * | |
5 * Copyright 2012 Tim Bird <tbird20d@gmail.com> | |
6 * | |
7 * See http://opengroup.org/onlinepubs/9699919799/utilities/find.html | |
8 | |
815
0c5b15cf4911
A couple quick fixes to find so I can try it out.
Rob Landley <rob@landley.net>
parents:
814
diff
changeset
|
9 USE_FIND(NEWTOY(find, "?", TOYFLAG_USR|TOYFLAG_BIN)) |
814 | 10 |
11 config FIND | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
12 bool "find" |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
13 default n |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
14 help |
1234
c99c215b4604
find: clarify and expand the help for find -type
Isaac Dunham <ibid.ag@gmail.com>
parents:
887
diff
changeset
|
15 usage: find [DIR] [<options>] |
814 | 16 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
17 -name <pattern> match pattern |
1234
c99c215b4604
find: clarify and expand the help for find -type
Isaac Dunham <ibid.ag@gmail.com>
parents:
887
diff
changeset
|
18 -type [bcdflps] match file type |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
19 !, -a, -o not, and , or |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
20 (, ) group expressions |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
21 -mtime [-+]n match file modification time (to within 24 hours) |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
22 \t\t +=greater (older) than, -=less (younger) than |
1234
c99c215b4604
find: clarify and expand the help for find -type
Isaac Dunham <ibid.ag@gmail.com>
parents:
887
diff
changeset
|
23 |
c99c215b4604
find: clarify and expand the help for find -type
Isaac Dunham <ibid.ag@gmail.com>
parents:
887
diff
changeset
|
24 File types: |
c99c215b4604
find: clarify and expand the help for find -type
Isaac Dunham <ibid.ag@gmail.com>
parents:
887
diff
changeset
|
25 b block device d directory l symlink s socket |
c99c215b4604
find: clarify and expand the help for find -type
Isaac Dunham <ibid.ag@gmail.com>
parents:
887
diff
changeset
|
26 c char device f regular file p FIFO |
814 | 27 */ |
28 | |
29 /* To Do: | |
30 * -exec action | |
31 */ | |
32 | |
849 | 33 #define FOR_find |
814 | 34 #include "toys.h" |
35 | |
36 struct filter_node { | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
37 struct filter_node *next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
38 int op; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
39 union { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
40 char *name_regex; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
41 struct { |
887 | 42 int sign; |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
43 time_t time; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
44 } t; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
45 mode_t type; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
46 struct { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
47 int arg_path_index; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
48 char **exec_args; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
49 } e; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
50 } data; |
814 | 51 }; |
52 | |
874 | 53 GLOBALS( |
54 char *dir; | |
55 struct filter_node *filter_root; | |
887 | 56 time_t itime; |
874 | 57 ) |
58 | |
814 | 59 /* filter operation types */ |
60 #define OP_UNKNOWN 0 | |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
61 #define OP_OR 2 |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
62 #define OP_AND 3 |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
63 #define OP_NOT 4 |
814 | 64 |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
65 #define LPAREN 1 |
814 | 66 #define RPAREN 5 |
67 | |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
68 #define MAX_OP 5 |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
69 |
814 | 70 #define CHECK_NAME 7 |
71 #define CHECK_MTIME 8 | |
72 #define CHECK_TYPE 9 | |
73 | |
74 #define ACTION_PRINT 20 | |
75 #define ACTION_PRINT0 21 | |
76 #define ACTION_EXEC 22 | |
77 | |
874 | 78 #define IS_ACTION(x) (x >= 20) |
79 | |
814 | 80 /* executes the command for a filter node |
875 | 81 returns 0 for failure or 1 for success |
814 | 82 */ |
847
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
83 static int do_exec(struct filter_node *filter, struct dirtree *node) |
814 | 84 { |
849 | 85 char *path = NULL; |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
86 char **arg_array; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
87 pid_t pid; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
88 int status; |
814 | 89 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
90 arg_array = filter->data.e.exec_args; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
91 if (filter->data.e.arg_path_index) { |
875 | 92 int plen; |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
93 path = dirtree_path(node, &plen); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
94 arg_array[filter->data.e.arg_path_index] = path; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
95 } |
816
3a7defbc671e
Remove more debug code from find.
Rob Landley <rob@landley.net>
parents:
815
diff
changeset
|
96 |
849 | 97 if (!(pid = fork())) xexec(arg_array); |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
98 free(path); |
849 | 99 waitpid(pid, &status, 0); |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
100 |
875 | 101 return !WEXITSTATUS(status); |
814 | 102 } |
103 | |
104 /* prefix evaluator */ | |
847
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
105 /* returns 0 for failure or 1 for success */ |
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
106 static int evaluate(struct filter_node *filter, struct dirtree *node, |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
107 struct filter_node **fnext) |
814 | 108 { |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
109 int result; |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
110 int op; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
111 static int skip = 0; |
814 | 112 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
113 /* if no filters, success */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
114 if (!filter) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
115 *fnext = NULL; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
116 return 1; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
117 } |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
118 op = filter->op; |
814 | 119 |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
120 if (op==OP_NOT) return !evaluate(filter->next, node, fnext); |
849 | 121 |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
122 if (op==OP_OR || op==OP_AND) { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
123 result = evaluate(filter->next, node, fnext); |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
124 if(!skip) { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
125 if (op==OP_OR) { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
126 skip = result; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
127 result = evaluate(*fnext, node, fnext) || result; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
128 } else { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
129 skip = !result; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
130 result = evaluate(*fnext, node, fnext) && result; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
131 } |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
132 skip = 0; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
133 } |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
134 else result = evaluate(*fnext, node, fnext); |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
135 return result; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
136 } |
849 | 137 |
138 // we're down to single operations, mark our position | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
139 *fnext = filter->next; |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
140 if(skip) return 0; |
849 | 141 |
142 // TODO: Do a regex comparison | |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
143 if (op==CHECK_NAME) |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
144 return !strcmp(filter->data.name_regex, node->name); |
849 | 145 |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
146 if (op==CHECK_MTIME) { |
887 | 147 long delta = (long)(((double)TT.itime - node->st.st_mtime) / 86400) |
148 -filter->data.t.time; | |
149 return filter->data.t.sign == (delta > 0) - (delta < 0); | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
150 } |
875 | 151 if (op==CHECK_TYPE) return (node->st.st_mode & S_IFMT) == filter->data.type; |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
152 |
814 | 153 |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
154 if (op==ACTION_PRINT || op==ACTION_PRINT0) { |
875 | 155 char *path; |
156 int plen = 0; | |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
157 char terminator = (op==ACTION_PRINT)*'\n'; |
849 | 158 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
159 path = dirtree_path(node, &plen); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
160 printf("%s%c", path, terminator); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
161 free(path); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
162 return 1; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
163 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
164 |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
165 if (op==ACTION_EXEC) return !do_exec(filter, node); |
849 | 166 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
167 error_msg("Ran out of operations in filter list!"); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
168 return 1; |
814 | 169 } |
170 | |
847
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
171 static int check_node_callback(struct dirtree *node) |
814 | 172 { |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
173 struct filter_node *junk; |
814 | 174 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
175 /* only recurse on "." at the root */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
176 /* so, don't recurse on 1) non-root "." and 2) any ".." */ |
816
3a7defbc671e
Remove more debug code from find.
Rob Landley <rob@landley.net>
parents:
815
diff
changeset
|
177 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
178 if (node->name[0] == '.' && |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
179 ((!node->name[1] && node->parent) || |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
180 (node->name[1]=='.' && !node->name[2]))) |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
181 return 0; |
814 | 182 |
875 | 183 evaluate(TT.filter_root, node, &junk); |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
184 return DIRTREE_RECURSE; |
814 | 185 } |
186 | |
187 | |
847
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
188 static void build_filter_list(void) |
814 | 189 { |
849 | 190 struct filter_node *node_list, *op_stack, *node, *op_node, *next; |
874 | 191 char **arg; |
192 int j; | |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
193 int prevop = 0; |
875 | 194 int have_action = 0; |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
195 |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
196 /* part optargs here and build a filter list in prefix format */ |
814 | 197 |
849 | 198 TT.dir = "."; |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
199 node_list = NULL; |
874 | 200 for (arg = toys.optargs; *arg; arg++) { |
201 struct { | |
202 char *arg; | |
203 int op; | |
204 int extrarg; | |
205 } arg_map[] = {{"-o", OP_OR, 0}, | |
206 {"-a", OP_AND, 0}, | |
207 {"!", OP_NOT, 0}, | |
208 {"(", LPAREN, 0}, | |
209 {")", RPAREN, 0}, | |
210 {"-name", CHECK_NAME, 1}, | |
211 {"-mtime", CHECK_MTIME, 1}, | |
212 {"-type", CHECK_TYPE, 1}, | |
213 {"-print", ACTION_PRINT, 0}, | |
214 {"-print0", ACTION_PRINT0, 0}, | |
215 {"-exec", ACTION_EXEC, 1} | |
216 }; | |
217 mode_t types[]={S_IFREG,S_IFDIR,S_IFCHR,S_IFBLK,S_IFLNK,S_IFSOCK,S_IFIFO}; | |
218 char **arg_array; | |
219 node = (struct filter_node *) xmalloc(sizeof(struct filter_node)); | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
220 node->op = OP_UNKNOWN; |
874 | 221 for (j=0; j < sizeof(arg_map)/sizeof(*arg_map); j++) { |
222 if (!strcmp(*arg, arg_map[j].arg)) { | |
223 node->op = arg_map[j].op; | |
224 if (arg_map[j].extrarg && !*(++arg)) | |
225 error_exit("Missing argument to %s", arg_map[j].arg); | |
226 break; | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
227 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
228 } |
814 | 229 |
874 | 230 switch(node->op) { |
231 case CHECK_NAME: | |
232 node->data.name_regex = *arg; | |
233 break; | |
234 case CHECK_MTIME: | |
235 switch(**arg) { | |
236 case '+': | |
887 | 237 node->data.t.sign=+1; |
238 (*arg)++; | |
874 | 239 break; |
240 case '-': | |
887 | 241 node->data.t.sign=-1; |
242 (*arg)++; | |
874 | 243 break; |
244 default: | |
887 | 245 node->data.t.sign=0; |
874 | 246 break; |
247 } | |
887 | 248 node->data.t.time = atoi(*arg); |
874 | 249 break; |
250 case CHECK_TYPE: | |
251 if (-1 == (j = stridx("fdcblsp", **arg))) | |
252 error_exit("bad type '%s'", *arg); | |
253 else node->data.type = types[j]; | |
254 break; | |
255 case ACTION_EXEC: | |
256 arg_array = xmalloc(sizeof(char *)); | |
257 for (j = 0; *arg && strcmp(*arg, ";"); j++) { | |
258 /* new method */ | |
259 arg_array = xrealloc(arg_array, sizeof(char *) * (j+2)); | |
260 arg_array[j] = *arg; | |
261 if (!strcmp(*arg, "{}")) node->data.e.arg_path_index = j; | |
849 | 262 |
874 | 263 arg++; |
264 } | |
265 if (!*arg) error_exit("need ';' in exec"); | |
266 arg_array[j] = 0; | |
267 node->data.e.exec_args = arg_array; | |
268 break; | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
269 } |
874 | 270 |
875 | 271 have_action |= IS_ACTION(node->op); |
814 | 272 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
273 if (node->op == OP_UNKNOWN) { |
874 | 274 if (**arg == '-') error_exit("bad option '%s'", *arg); |
275 else TT.dir = *arg; | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
276 } else { |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
277 // add OP_AND where necessary |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
278 if (node_list) { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
279 int o1 = node_list->op, o2 = node->op; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
280 if ((o1>MAX_OP && o2>MAX_OP) || |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
281 (o1==RPAREN && o2>=OP_NOT && o2!=RPAREN) || |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
282 (o1>=OP_NOT && o1!=LPAREN && o2==LPAREN)) { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
283 struct filter_node *n = (struct filter_node *) |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
284 xmalloc(sizeof(struct filter_node)); |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
285 n->op = OP_AND; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
286 n->next = node_list; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
287 node_list = n; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
288 } |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
289 } |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
290 /* push node */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
291 node->next = node_list;; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
292 node_list = node; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
293 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
294 |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
295 } |
814 | 296 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
297 /* now convert from infix to prefix */ |
875 | 298 if(have_action) TT.filter_root = NULL; |
299 else TT.filter_root = &(struct filter_node){0, ACTION_PRINT}; | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
300 op_stack = NULL; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
301 node = node_list; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
302 while( node ) { |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
303 int op = node->op; |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
304 next = node->next; |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
305 if (op==LPAREN || op==RPAREN) { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
306 free(node); |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
307 node = 0; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
308 } |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
309 if (op<=MAX_OP) { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
310 if (prevop > op) { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
311 /* pop opstack to output */ |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
312 op_node = op_stack; |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
313 while (op_node) { |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
314 /* remove from op_stack */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
315 op_stack = op_node->next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
316 /* push to output */ |
874 | 317 op_node->next = TT.filter_root; |
318 TT.filter_root = op_node; | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
319 /* get next node */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
320 op_node = op_stack; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
321 } |
867
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
322 } |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
323 if (node) { |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
324 /* push to opstack */ |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
325 node->next = op_stack; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
326 op_stack = node; |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
327 } |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
328 prevop = op*(op!=RPAREN); |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
329 } |
1700c6bfc8f5
find: Improve operator processing
Felix Janda <felix.janda@posteo.de>
parents:
849
diff
changeset
|
330 else { |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
331 /* push to output */ |
874 | 332 node->next = TT.filter_root; |
333 TT.filter_root = node; | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
334 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
335 node = next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
336 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
337 /* end of input - push opstack to output */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
338 /* pop opstack to output till empty */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
339 op_node = op_stack; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
340 while (op_node) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
341 op_stack = op_node->next; |
874 | 342 op_node->next = TT.filter_root; |
343 TT.filter_root = op_node; | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
344 op_node = op_stack; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
345 } |
875 | 346 if(!have_action) { |
347 node = TT.filter_root; | |
348 TT.filter_root = (struct filter_node*) xmalloc(sizeof(struct filter_node)); | |
349 TT.filter_root->next = node; | |
350 TT.filter_root->op = OP_AND; | |
351 } | |
814 | 352 } |
353 | |
354 void find_main(void) | |
355 { | |
887 | 356 TT.itime = time(NULL); |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
357 /* parse filters, if present */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
358 build_filter_list(); |
814 | 359 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
360 /* FIXTHIS - parse actions, if present */ |
814 | 361 |
849 | 362 dirtree_read(TT.dir, check_node_callback); |
814 | 363 } |