1 /*
2  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * BSD 3 Clause License
8  *
9  * Copyright (c) 2007, The Storage Networking Industry Association.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 	- Redistributions of source code must retain the above copyright
15  *	  notice, this list of conditions and the following disclaimer.
16  *
17  * 	- Redistributions in binary form must reproduce the above copyright
18  *	  notice, this list of conditions and the following disclaimer in
19  *	  the documentation and/or other materials provided with the
20  *	  distribution.
21  *
22  *	- Neither the name of The Storage Networking Industry Association (SNIA)
23  *	  nor the names of its contributors may be used to endorse or promote
24  *	  products derived from this software without specific prior written
25  *	  permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * This file defines macros and constants related to traversing file
42  * system hieratchy in post-order, pre-order and level-order ways.
43  */
44 
45 #ifndef _TRAVERSE_H_
46 #define	_TRAVERSE_H_
47 
48 #ifdef __cplusplus
49 extern "C" {
50 #endif
51 
52 /*
53  * Library functions for traversing file system hierarchy in
54  * post-order, pre-order and level-order.
55  *
56  * This example will be used in the following descriptions.
57  * All alphabetical entries are directory and all the numerical
58  * entries are non-directory entries.
59  *
60  * AAA
61  * AAA/BBB
62  * AAA/BBB/1
63  * AAA/BBB/2
64  * AAA/BBB/3
65  * AAA/CCC
66  * AAA/CCC/EEE
67  * AAA/CCC/EEE/4
68  * AAA/CCC/EEE/5
69  * AAA/CCC/EEE/6
70  * AAA/CCC/EEE/7
71  * AAA/CCC/EEE/8
72  * AAA/CCC/9
73  * AAA/XXX
74  * AAA/ZZZ
75  * AAA/10
76  * AAA/11
77  * AAA/12
78  * AAA/13
79  *
80  * Each traversing function gets an argument of 'struct fs_traverse *'
81  * type.  The fields of this structure are explained below.
82  *
83  * For each entry while traversing, the callback function is
84  * called and three arguments are passed to it.  The argument
85  * specified in the struct fs_traverse, a struct fst_node for the
86  * path and a struct fst_node for the entry.
87  *
88  * For the root of the traversing, the fields of struct fst_node
89  * of the entry are all NULL.
90  *
91  * If the path to be traversed is not a directory, the callback
92  * function is called on it.  The fields of the 'struct fst_node'
93  * argument for entry are all NULL.
94  *
95  *
96  * POST-ORDER:
97  * Post-order means that the directory is processed after all
98  * its children are processed.  Post-order traversing of the above
99  * hierarchy will be like this:
100  *
101  * AAA/BBB, 1
102  * AAA/BBB, 2
103  * AAA/BBB, 3
104  * AAA, BBB
105  * AAA/CCC/EEE, 6
106  * AAA/CCC/EEE, 5
107  * AAA/CCC/EEE, 8
108  * AAA/CCC/EEE, 4
109  * AAA/CCC/EEE, 7
110  * AAA/CCC, EEE
111  * AAA/CCC, 9
112  * AAA, CCC
113  * AAA, XXX
114  * AAA, ZZZ
115  * AAA, 10
116  * AAA, 11
117  * AAA, 12
118  * AAA, 13
119  * AAA
120  *
121  * In post-order the callback function returns 0 on success
122  * or non-zero to stop further traversing the hierarchy.
123  *
124  * One of the applications of post-order traversing of a
125  * hierarchy can be deleting the hierarchy from the file system.
126  *
127  *
128  * PRE-ORDER:
129  * Pre-order means that the directory is processed before
130  * any of its children are processed.  Pre-order traversing of
131  * the above hierarchy will be like this:
132  *
133  * AAA
134  * AAA, BBB
135  * AAA/BBB, 1
136  * AAA/BBB, 2
137  * AAA/BBB, 3
138  * AAA, CCC
139  * AAA/CCC, EEE
140  * AAA/CCC/EEE, 6
141  * AAA/CCC/EEE, 5
142  * AAA/CCC/EEE, 8
143  * AAA/CCC/EEE, 4
144  * AAA/CCC/EEE, 7
145  * AAA/CCC, 9
146  * AAA, XXX
147  * AAA, ZZZ
148  * AAA, 10
149  * AAA, 11
150  * AAA, 12
151  * AAA, 13
152  *
153  * In pre-order, the callback function can return 3 values:
154  *     0: means that the traversing should continue.
155  *
156  *     < 0: means that the traversing should be stopped immediately.
157  *
158  *     FST_SKIP: means that no further entries of this directory
159  *         should be processed.  Traversing continues with the
160  *         next directory of the same level.  For example, if
161  *         callback returns FST_SKIP on AAA/BBB, the callback
162  *         will not be called on 1, 2, 3 and traversing will
163  *         continue with AAA/CCC.
164  *
165  *
166  * LEVEL-ORDER:
167  * This is a special case of pre-order.  In this method,
168  * all the non-directory entries of a directory are processed
169  * and then come the directory entries.  Level-order traversing
170  * of the above hierarchy will be like this:
171  *
172  * AAA
173  * AAA, 10
174  * AAA, 11
175  * AAA, 12
176  * AAA, 13
177  * AAA, BBB
178  * AAA/BBB, 1
179  * AAA/BBB, 2
180  * AAA/BBB, 3
181  * AAA, CCC
182  * AAA/CCC, 9
183  * AAA/CCC, EEE
184  * AAA/CCC/EEE, 6
185  * AAA/CCC/EEE, 5
186  * AAA/CCC/EEE, 8
187  * AAA/CCC/EEE, 4
188  * AAA/CCC/EEE, 7
189  * AAA, XXX
190  * AAA, ZZZ
191  *
192  * The rules of pre-order for the return value of callback
193  * function applies for level-order.
194  */
195 
196 #include <sys/types.h>
197 #include <sys/stat.h>
198 #include "tlm.h"
199 
200 /*
201  * To prune a directory when traversing it, this return
202  * value should be returned by the callback function in
203  * level-order and pre-order traversing.
204  *
205  * In level-order processing, this return value stops
206  * reading the rest of the directory and calling the callback
207  * function for them.  Traversing will continue with the next
208  * directory of the same level.  The children of the current
209  * directory will be pruned too.  For example on this ,
210  *
211  */
212 #define	FST_SKIP	1
213 
214 
215 #define	SKIP_ENTRY	2
216 
217 
218 /*
219  * Directives for traversing file system.
220  *
221  * FST_STOP_ONERR: Stop travergins when stat fails on an entry.
222  * FST_STOP_ONLONG: Stop on detecting long path.
223  * FST_VERBOSE: Verbose running.
224  */
225 #define	FST_STOP_ONERR		0x00000001
226 #define	FST_STOP_ONLONG		0x00000002
227 #define	FST_VERBOSE		0x80000000
228 
229 
230 typedef void (*ft_log_t)();
231 
232 
233 /*
234  * The arguments of traversing file system contains:
235  *     path: The physical path to be traversed.
236  *
237  *     lpath	The logical path to be passed to the callback
238  *         	function as path.
239  *         	If this is set to NULL, the default value will be
240  *         	the 'path'.
241  *
242  *         	For example, traversing '/v1.chkpnt/backup/home' as
243  *         	physical path can have a logical path of '/v1/home'.
244  *
245  *     flags	Show how the traversing should be done.
246  *         	Values of this field are of FST_ constants.
247  *
248  *     callbk	The callback function pointer.  The callback
249  *         	function is called like this:
250  *         	(*ft_callbk)(
251  *         		void *ft_arg,
252  *         		struct fst_node *path,
253  *         		struct fst_node *entry)
254  *
255  *     arg	The 'void *' argument to be passed to the call
256  *		back function.
257  *
258  *     logfp	The log function pointer.  This function
259  *         	is called to log the messages.
260  *         	Default is logf().
261  */
262 typedef struct fs_traverse {
263 	char *ft_path;
264 	char *ft_lpath;
265 	unsigned int ft_flags;
266 	int (*ft_callbk)();
267 	void *ft_arg;
268 	ft_log_t ft_logfp;
269 } fs_traverse_t;
270 
271 /*
272  * Traversing Nodes.  For each path and node upon entry this
273  * structure is passed to the callback function.
274  */
275 typedef struct fst_node {
276 	char *tn_path;
277 	fs_fhandle_t *tn_fh;
278 	struct stat64 *tn_st;
279 } fst_node_t;
280 
281 extern int traverse_post(fs_traverse_t *);
282 extern int traverse_pre(fs_traverse_t *);
283 extern int traverse_level(fs_traverse_t *);
284 #undef	getdents
285 extern int getdents(int, struct dirent *, size_t);
286 #ifdef __cplusplus
287 }
288 #endif
289 
290 #endif /* _TRAVERSE_H_ */
291