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