1 /* @(#)walk.h	1.39 19/11/28 Copyright 2004-2019 J. Schilling */
2 /*
3  *	Definitions for directory tree walking
4  *
5  *	Copyright (c) 2004-2019 J. Schilling
6  */
7 /*
8  * The contents of this file are subject to the terms of the
9  * Common Development and Distribution License, Version 1.0 only
10  * (the "License").  You may not use this file except in compliance
11  * with the License.
12  *
13  * See the file CDDL.Schily.txt in this distribution for details.
14  * A copy of the CDDL is also available via the Internet at
15  * http://www.opensource.org/licenses/cddl1.txt
16  *
17  * When distributing Covered Code, include this CDDL HEADER in each
18  * file and include the License file CDDL.Schily.txt from this distribution.
19  */
20 
21 #ifndef	_SCHILY_WALK_H
22 #define	_SCHILY_WALK_H
23 
24 #ifndef _SCHILY_MCONFIG_H
25 #include <schily/mconfig.h>
26 #endif
27 
28 #ifndef _SCHILY_TYPES_H
29 #include <schily/types.h>
30 #endif
31 #ifndef _SCHILY_STAT_H
32 #include <schily/stat.h>
33 #endif
34 
35 #ifndef _SCHILY_STDIO_H
36 #include <schily/stdio.h>
37 #endif
38 
39 #ifdef	__cplusplus
40 extern "C" {
41 #endif
42 
43 /*
44  * Flags to control treewalk() via 'walkflags'.
45  *
46  *	WALK_CHDIR	Change directory while traversing
47  *
48  *	WALK_PHYS	Clearing WALK_PHYS has highest precedence and equals
49  *			'find -follow'. If WALK_PHYS is clear, always use stat.
50  *			By default, WALK_PHYS should be set.
51  *
52  *	WALK_ARGFOLLOW	If WALK_ARGFOLLOW is set, symlinks that are used as
53  *			the first argument for trewalk() are followed even
54  *			if WALK_PHYS is set. Setting WALK_ARGFOLLOW equals
55  *			'find -H'.
56  *
57  *	WALK_ALLFOLLOW	If WALK_ALLFOLLOW is set, all symlinks are followed
58  *			even if WALK_PHYS is set. Setting WALK_ALLFOLLOW
59  *			equals 'find -L'.
60  */
61 #define	WALK_PHYS	1	/* Use lstat() instead of stat()	*/
62 #define	WALK_MOUNT	2	/* Do not cross mount points		*/
63 #define	WALK_DEPTH	4	/* Call content before calling the dir	*/
64 #define	WALK_CHDIR	8	/* Use chdir() to each directory	*/
65 #define	WALK_ARGFOLLOW	0x10	/* Use stat() for top level args only	*/
66 #define	WALK_ALLFOLLOW	0x20	/* Use stat() for all files		*/
67 #define	WALK_NOSTAT	0x40	/* Avoid to call stat() if st_nlink =>2 */
68 #define	WALK_NOEXIT	0x100	/* Do not exit() in case of hard errors	*/
69 #define	WALK_NOMSG	0x200	/* Do not write messages to stderr	*/
70 #define	WALK_LS_ATIME	0x1000	/* -ls lists atime instead of mtime	*/
71 #define	WALK_LS_CTIME	0x2000	/* -ls lists ctime instead of mtime	*/
72 #define	WALK_STRIPLDOT	0x4000	/* Strip leading "./" from path		*/
73 #define	WALK_MOUNTPLUS	0x8000	/* Do not continue at mount points	*/
74 #define	WALK_XDEV	0x8000	/* Do not continue at mount points	*/
75 
76 /*
77  * The 'type' argument to walkfun.
78  */
79 #define	WALK_NONE	0	/* Used when not called from treewalk()	*/
80 #define	WALK_F		1	/* File	*/
81 #define	WALK_SL		2	/* Symbolic Link */
82 #define	WALK_D		3	/* Directory */
83 #define	WALK_DP		4	/* Directory previously visited */
84 #define	WALK_DNR	5	/* Directory with no read permission */
85 #define	WALK_NS		6	/* Unknown file type stat failed */
86 #define	WALK_SLN	7	/* Symbolic Link points to nonexistent file */
87 
88 #ifndef	__sqfun_t_defined
89 typedef	int	(*sqfun_t)	__PR((void *arg));
90 #define	__sqfun_t_defined
91 #endif
92 
93 #ifndef	__cbfun_t_defined
94 typedef	int	(*cbfun_t)	__PR((int ac, char  **argv));
95 #define	__cbfun_t_defined
96 #endif
97 
98 struct WALK {
99 	int	flags;		/* Flags for communication with (*walkfun)() */
100 	int	level;		/* The nesting level set up for (*walkfun)() */
101 	size_t	base;		/* Filename offset in path for  (*walkfun)() */
102 	int	walkflags;	/* treewalk() control flags		    */
103 	void	*twprivate;	/* treewalk() private do not touch	    */
104 	FILE	*std[3];	/* To redirect stdin/stdout/err in treewalk  */
105 	char	**env;		/* To allow different env in treewalk/exec   */
106 	sqfun_t	quitfun;	/* Function to query for shell signal quit   */
107 	void	*qfarg;		/* Generic arg for shell builtin quit fun    */
108 	int	maxdepth;	/* (*walkfun)() private, unused by treewalk  */
109 	int	mindepth;	/* (*walkfun)() private, unused by treewalk  */
110 	char	*lname;		/* (*walkfun)() private, unused by treewalk  */
111 	void	*tree;		/* (*walkfun)() private, unused by treewalk  */
112 	void	*patstate;	/* (*walkfun)() private, unused by treewalk  */
113 	int	err;		/* (*walkfun)() private, unused by treewalk  */
114 	int	pflags;		/* (*walkfun)() private, unused by treewalk  */
115 	int	auxi;		/* (*walkfun)() private, unused by treewalk  */
116 	void	*auxp;		/* (*walkfun)() private, unused by treewalk  */
117 	void	*__reserved[16]; /* For future extensions		    */
118 };
119 
120 /*
121  * Flags in struct WALK used to communicate with (*walkfun)()
122  */
123 #define	WALK_WF_PRUNE	1	/* (*walkfun)() -> walk(): abort waking tree */
124 #define	WALK_WF_QUIT	2	/* (*walkfun)() -> walk(): quit completely   */
125 #define	WALK_WF_NOCHDIR	4	/* walk() -> (*walkfun)(): WALK_DNR w chdir() */
126 #define	WALK_WF_NOCWD	8	/* walk() -> caller: cannot get working dir  */
127 #define	WALK_WF_NOHOME	16	/* walk() -> caller: cannot chdir("..")	    */
128 #define	WALK_WF_NOTDIR	32	/* walk() -> walk(): file is not a directory */
129 #define	WALK_WF_ISLNK	64	/* walk() -> walk(): file is a symlink	    */
130 
131 #define	WALK_WF_CHOWN	4096	/* (*walkfun)(): changed st_uid or st_gid */
132 #define	WALK_WF_CHMOD	8192	/* (*walkfun)(): changed st_mode */
133 #define	WALK_WF_CHTIME	16384	/* (*walkfun)(): changed st_mtime or st_ctime */
134 
135 typedef	int	(*walkfun)	__PR((char *_nm, struct stat *_fs, int _type,
136 						struct WALK *_state));
137 
138 extern	int	treewalk	__PR((char *_nm, walkfun _fn,
139 						struct WALK *_state));
140 extern	void	walkinitstate	__PR((struct WALK *_state));
141 extern	void	*walkopen	__PR((struct WALK *_state));
142 extern	int	walkgethome	__PR((struct WALK *_state));
143 extern	int	walkhome	__PR((struct WALK *_state));
144 extern	int	walkcwd		__PR((struct WALK *_state));
145 extern	int	walkclose	__PR((struct WALK *_state));
146 extern	size_t	walknlen	__PR((struct WALK *_state));
147 extern	void	walksname	__PR((char *_nm, struct WALK *_state));
148 
149 #ifdef	__cplusplus
150 }
151 #endif
152 
153 #endif	/* _SCHILY_WALK_H */
154