Mercurial > hg > toybox
annotate toys/pending/find.c @ 848:feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
author | Rob Landley <rob@landley.net> |
---|---|
date | Wed, 10 Apr 2013 19:58:21 -0500 |
parents | 2506cbdccd20 |
children | 917d6e051b82 |
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 |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
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 |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
18 -type [fcdl] match file type |
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 |
814 | 23 */ |
24 | |
25 /* To Do: | |
26 * -exec action | |
27 */ | |
28 | |
29 #include "toys.h" | |
30 | |
31 #define SECONDS_PER_DAY (24*60*60) | |
32 | |
33 int have_action; | |
34 | |
35 struct filter_node { | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
36 struct filter_node *next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
37 int op; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
38 union { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
39 char *name_regex; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
40 struct { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
41 char time_op; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
42 time_t time; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
43 } t; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
44 mode_t type; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
45 struct { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
46 int arg_path_index; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
47 char **exec_args; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
48 } e; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
49 } data; |
814 | 50 }; |
51 | |
52 static struct filter_node *filter_root; | |
53 | |
54 /* filter operation types */ | |
55 #define OP_UNKNOWN 0 | |
56 #define OP_NOT 1 | |
57 #define OP_OR 2 | |
58 #define OP_AND 3 | |
59 | |
60 #define LPAREN 4 | |
61 #define RPAREN 5 | |
62 | |
63 #define CHECK_NAME 7 | |
64 #define CHECK_MTIME 8 | |
65 #define CHECK_TYPE 9 | |
66 | |
67 #define ACTION_PRINT 20 | |
68 #define ACTION_PRINT0 21 | |
69 #define ACTION_EXEC 22 | |
70 | |
71 #define TEST_LT 0 | |
72 #define TEST_EQ 1 | |
73 #define TEST_GT 2 | |
74 | |
75 /* executes the command for a filter node | |
76 * return the program return value (0=success) | |
77 */ | |
847
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
78 static int do_exec(struct filter_node *filter, struct dirtree *node) |
814 | 79 { |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
80 char *path; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
81 int plen; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
82 char **arg_array; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
83 pid_t pid; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
84 int ccode; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
85 int status; |
814 | 86 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
87 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
|
88 if (filter->data.e.arg_path_index) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
89 path = dirtree_path(node, &plen); |
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.arg_path_index] = path; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
91 } else { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
92 path = NULL; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
93 } |
816
3a7defbc671e
Remove more debug code from find.
Rob Landley <rob@landley.net>
parents:
815
diff
changeset
|
94 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
95 pid = fork(); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
96 if (!pid) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
97 /* child */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
98 xexec(arg_array); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
99 } else { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
100 /* parent */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
101 /* wait for child */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
102 waitpid(pid, &status, 0); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
103 ccode = WEXITSTATUS(status); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
104 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
105 free(path); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
106 |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
107 return ccode; |
814 | 108 } |
109 | |
110 /* prefix evaluator */ | |
847
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
111 /* returns 0 for failure or 1 for success */ |
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
112 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
|
113 struct filter_node **fnext) |
814 | 114 { |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
115 int result; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
116 char *path; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
117 int plen = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
118 struct stat st_buf; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
119 time_t node_time; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
120 char terminator; |
814 | 121 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
122 /* if no filters, success */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
123 if (!filter) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
124 *fnext = NULL; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
125 return 1; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
126 } |
814 | 127 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
128 if (filter->op==OP_NOT) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
129 return !evaluate(filter->next, node, fnext); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
130 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
131 if (filter->op==OP_OR) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
132 return evaluate(filter->next, node, fnext) || evaluate(*fnext, node, fnext); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
133 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
134 if (filter->op==OP_AND) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
135 return evaluate(filter->next, node, fnext) && evaluate(*fnext, node, fnext); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
136 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
137 /* we're down to single operations, mark our position */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
138 *fnext = filter->next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
139 if (filter->op==CHECK_NAME) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
140 // TODO: Do a regex comparison |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
141 return !strcmp(filter->data.name_regex, node->name); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
142 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
143 if (filter->op==CHECK_MTIME) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
144 /* do mtime check */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
145 path = dirtree_path(node, &plen); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
146 result = stat(path, &st_buf); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
147 free(path); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
148 if (result<0) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
149 return 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
150 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
151 node_time = st_buf.st_mtime/SECONDS_PER_DAY; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
152 result = 1; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
153 switch (filter->data.t.time_op) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
154 /* do time compare here */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
155 case TEST_LT: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
156 /* FIXTHIS - should result be < or <= ?*/ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
157 if (node_time > filter->data.t.time) |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
158 result = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
159 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
160 case TEST_GT: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
161 if (node_time < filter->data.t.time) |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
162 result = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
163 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
164 case TEST_EQ: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
165 if (node_time != filter->data.t.time) |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
166 result = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
167 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
168 default: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
169 /* how'd I get here? */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
170 result = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
171 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
172 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
173 return result; |
814 | 174 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
175 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
176 if (filter->op==CHECK_TYPE) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
177 path = dirtree_path(node, &plen); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
178 result = lstat(path, &st_buf); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
179 free(path); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
180 if (result<0) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
181 return 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
182 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
183 return (st_buf.st_mode & S_IFMT) == filter->data.type; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
184 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
185 |
814 | 186 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
187 if (filter->op==ACTION_PRINT || filter->op==ACTION_PRINT0) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
188 if (filter->op==ACTION_PRINT) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
189 terminator = '\n'; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
190 } else { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
191 terminator = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
192 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
193 path = dirtree_path(node, &plen); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
194 printf("%s%c", path, terminator); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
195 free(path); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
196 return 1; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
197 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
198 |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
199 if (filter->op==ACTION_EXEC) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
200 return !do_exec(filter, node); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
201 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
202 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
|
203 return 1; |
814 | 204 } |
205 | |
847
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
206 static int check_node_callback(struct dirtree *node) |
814 | 207 { |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
208 char *path; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
209 int plen = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
210 int result; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
211 struct filter_node *junk; |
814 | 212 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
213 /* 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
|
214 /* 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
|
215 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
216 if (node->name[0] == '.' && |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
217 ((!node->name[1] && node->parent) || |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
218 (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
|
219 return 0; |
814 | 220 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
221 result = evaluate(filter_root, node, &junk); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
222 if (result & !have_action) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
223 /* default action is just print the path */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
224 path = dirtree_path(node, &plen); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
225 printf("%s\n", path); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
226 free(path); |
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 return DIRTREE_RECURSE; |
814 | 229 } |
230 | |
231 | |
847
2506cbdccd20
Partial cleanup of find
Felix Janda <felix.janda@posteo.de>
parents:
816
diff
changeset
|
232 static void build_filter_list(void) |
814 | 233 { |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
234 struct filter_node *node_list; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
235 struct filter_node *op_stack; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
236 struct filter_node *node, *op_node; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
237 struct filter_node *next; |
814 | 238 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
239 char *arg, **arg_array; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
240 int i, j; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
241 |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
242 /* part optargs here and build a filter list in prefix format */ |
814 | 243 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
244 node_list = NULL; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
245 toybuf[0] = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
246 have_action = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
247 for(i=0; toys.optargs[i]; i++) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
248 node = (struct filter_node *) |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
249 xmalloc(sizeof(struct filter_node)); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
250 node->op = OP_UNKNOWN; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
251 arg = toys.optargs[i]; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
252 if (!strcmp(arg, "-o")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
253 node->op = OP_OR; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
254 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
255 if (!strcmp(arg, "-a")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
256 node->op = OP_AND; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
257 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
258 if (!strcmp(arg, "!")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
259 node->op = OP_NOT; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
260 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
261 if (!strcmp(arg, "(")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
262 node->op = LPAREN; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
263 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
264 if (!strcmp(arg, ")")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
265 node->op = RPAREN; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
266 } |
814 | 267 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
268 if (!strcmp(arg, "-name")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
269 node->op = CHECK_NAME; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
270 arg = toys.optargs[++i]; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
271 if (!arg) error_exit("Missing argument to -name\n"); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
272 node->data.name_regex = arg; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
273 } |
814 | 274 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
275 if (!strcmp(arg, "-mtime")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
276 node->op = CHECK_MTIME; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
277 arg = toys.optargs[++i]; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
278 if (!arg) error_exit("Missing argument to -mtime\n"); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
279 switch(arg[0]) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
280 case '+': |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
281 node->data.t.time_op=TEST_GT; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
282 arg++; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
283 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
284 case '-': |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
285 node->data.t.time_op=TEST_LT; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
286 arg++; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
287 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
288 default: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
289 node->data.t.time_op=TEST_EQ; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
290 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
291 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
292 /* convert to days (very crudely) */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
293 node->data.t.time = atoi(arg)/SECONDS_PER_DAY; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
294 } |
814 | 295 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
296 if (!strcmp(arg, "-type")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
297 node->op = CHECK_TYPE; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
298 arg = toys.optargs[++i]; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
299 if (!arg) error_exit("Missing argument to -type\n"); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
300 switch(arg[0]) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
301 case 'f': |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
302 node->data.type = S_IFREG; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
303 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
304 case 'd': |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
305 node->data.type = S_IFDIR; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
306 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
307 case 'c': |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
308 node->data.type = S_IFCHR; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
309 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
310 case 'b': |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
311 node->data.type = S_IFBLK; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
312 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
313 case 'l': |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
314 node->data.type = S_IFLNK; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
315 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
316 case 's': |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
317 node->data.type = S_IFSOCK; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
318 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
319 case 'p': |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
320 /* named pipe */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
321 node->data.type = S_IFIFO; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
322 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
323 default: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
324 error_exit("Unknown file type '%s'\n", arg); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
325 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
326 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
327 if (!strcmp(arg, "-print")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
328 node->op = ACTION_PRINT; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
329 have_action = 1; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
330 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
331 if (!strcmp(arg, "-print0")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
332 node->op = ACTION_PRINT0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
333 have_action = 1; |
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 if (!strcmp(arg, "-exec")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
336 node->op = ACTION_EXEC; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
337 have_action = 1; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
338 arg_array = xmalloc(sizeof(char *)); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
339 arg = toys.optargs[++i]; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
340 for (j = 0; arg && strcmp(arg, ";"); j++) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
341 /* new method */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
342 arg_array = xrealloc(arg_array, sizeof(char *) * (j+2)); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
343 arg_array[j] = arg; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
344 if (!strcmp(arg, "{}")) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
345 node->data.e.arg_path_index = j; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
346 } |
814 | 347 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
348 arg = toys.optargs[++i]; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
349 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
350 if (!arg) error_exit("Missing ';' in exec command\n"); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
351 arg_array[j] = 0; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
352 node->data.e.exec_args = arg_array; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
353 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
354 if (node->op == OP_UNKNOWN) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
355 if (arg[0] == '-') error_exit("Unknown option '%s'\n", arg); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
356 else { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
357 /* use toybuf as start directory */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
358 strcpy(toybuf, arg); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
359 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
360 } else { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
361 /* push node */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
362 node->next = node_list;; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
363 node_list = node; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
364 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
365 |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
366 } |
814 | 367 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
368 /* now convert from infix to prefix */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
369 filter_root = NULL; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
370 op_stack = NULL; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
371 node = node_list; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
372 while( node ) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
373 next = node->next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
374 switch( node->op ) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
375 case OP_AND: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
376 case OP_OR: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
377 case OP_NOT: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
378 case RPAREN: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
379 /* push to opstack */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
380 node->next = op_stack; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
381 op_stack = node; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
382 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
383 case LPAREN: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
384 free(node); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
385 /* pop opstack to output (up to rparen) */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
386 op_node = op_stack; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
387 while (op_node && op_node->op != RPAREN) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
388 /* remove from op_stack */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
389 op_stack = op_node->next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
390 /* push to output */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
391 op_node->next = filter_root; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
392 filter_root = op_node; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
393 /* get next node */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
394 op_node = op_stack; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
395 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
396 /* rparen should be on op_stack */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
397 if (!op_stack) error_exit("Missing right paren\n"); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
398 /* remove rparen from op_stack */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
399 op_stack = op_stack->next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
400 free(op_node); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
401 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
402 default: |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
403 /* push to output */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
404 node->next = filter_root; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
405 filter_root = node; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
406 break; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
407 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
408 node = next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
409 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
410 /* 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
|
411 /* 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
|
412 op_node = op_stack; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
413 while (op_node) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
414 /*if (op_node->op == RPAREN || op_node->op == LPAREN) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
415 error_exit("Error: extra paren found\n"); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
416 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
417 */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
418 op_stack = op_node->next; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
419 op_node->next = filter_root; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
420 filter_root = op_node; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
421 op_node = op_stack; |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
422 } |
814 | 423 } |
424 | |
425 void find_main(void) | |
426 { | |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
427 /* parse filters, if present */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
428 /* also, fill toybuf with the directory to start in, if present */ |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
429 build_filter_list(); |
814 | 430 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
431 /* FIXTHIS - parse actions, if present */ |
814 | 432 |
848
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
433 if (!toybuf[0]) { |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
434 strcpy(toybuf, "."); |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
435 } |
feea7a8ecbb1
Redo find's indenting from tabs to two spaces.
Rob Landley <rob@landley.net>
parents:
847
diff
changeset
|
436 dirtree_read(toybuf, check_node_callback); |
814 | 437 } |