8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / lib / libshell / common / scripts / filetree1.sh
blob9cbcb0c35d89668d8e4ec7b8e738bdde148c551f
1 #!/usr/bin/ksh93
4 # CDDL HEADER START
6 # The contents of this file are subject to the terms of the
7 # Common Development and Distribution License (the "License").
8 # You may not use this file except in compliance with the License.
10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 # or http://www.opensolaris.org/os/licensing.
12 # See the License for the specific language governing permissions
13 # and limitations under the License.
15 # When distributing Covered Code, include this CDDL HEADER in each
16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 # If applicable, add the following below this CDDL HEADER, with the
18 # fields enclosed by brackets "[]" replaced with your own identifying
19 # information: Portions Copyright [yyyy] [name of copyright owner]
21 # CDDL HEADER END
25 # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 # Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant
29 export PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin
31 # Make sure all math stuff runs in the "C" locale to avoid problems
32 # with alternative # radix point representations (e.g. ',' instead of
33 # '.' in de_DE.*-locales). This needs to be set _before_ any
34 # floating-point constants are defined in this script).
35 if [[ "${LC_ALL}" != "" ]] ; then
36 export \
37 LC_MONETARY="${LC_ALL}" \
38 LC_MESSAGES="${LC_ALL}" \
39 LC_COLLATE="${LC_ALL}" \
40 LC_CTYPE="${LC_ALL}"
41 unset LC_ALL
43 export LC_NUMERIC=C
45 function fatal_error
47 print -u2 "${progname}: $*"
48 exit 1
52 function do_directory
54 nameref tree=$1
55 typeset basedir="$2"
57 typeset basename
58 typeset dirname
59 typeset i
60 typeset dummy
62 typeset -C -A tree.files
63 typeset -C -A tree.dirs
65 find "${basedir}"/* -prune 2>/dev/null | while read i ; do
66 dirname="$(dirname "$i")"
67 basename="$(basename "$i")"
69 # define "node"
70 if [[ -d "$i" ]] ; then
71 typeset -C tree.dirs["${basename}"]
72 nameref node=tree.dirs["${basename}"]
73 typeset -C node.flags
74 node.flags.dir="true"
75 node.flags.file="false"
76 else
77 typeset -C tree.files["${basename}"]
78 nameref node=tree.files["${basename}"]
79 typeset -C node.flags
81 node.flags.dir="false"
82 node.flags.file="true"
85 # basic attributes
86 typeset -C node.paths=(
87 dirname="${dirname}"
88 basename="${basename}"
89 path="${i}"
92 nameref nflags=node.flags
93 [[ -r "$i" ]] && nflags.readable="true" || nflags.readable="false"
94 [[ -w "$i" ]] && nflags.writeable="true" || nflags.writeable="false"
95 [[ -x "$i" ]] && nflags.executable="true" || nflags.executable="false"
97 [[ -b "$i" ]] && nflags.blockdevice="true" || nflags.blockdevice="false"
98 [[ -c "$i" ]] && nflags.characterdevice="true" || nflags.characterdevice="false"
99 [[ -S "$i" ]] && nflags.socket="true" || nflags.socket="false"
101 [[ -L "$i" ]] && nflags.symlink="true" || nflags.symlink="false"
103 integer node.size
104 integer node.links
105 typeset -C node.owner
106 ( [[ -x /usr/bin/runat ]] && ls -@ade "$i" || ls -lade "$i" ) |
107 IFS=' ' read \
108 node.mask \
109 node.links \
110 node.owner.uid \
111 node.owner.gid \
112 node.size \
113 dummy
115 typeset -C node.extended_attributes
116 if [[ ${node.mask} == ~(Er)@ ]] ; then
117 node.extended_attributes.hasattrs="true"
118 typeset -a attrlist=(
119 $( runat "$i" "ls -1" )
121 else
122 node.extended_attributes.hasattrs="false"
125 if ${nflags.readable} ; then
126 # note that /usr/xpg4/bin/file does not use $'\t' as seperator - we
127 # have to use ':' instead.
128 file -h "$i" | IFS=' ' read dummy node.filetype
131 if ${nflags.dir} ; then
132 do_directory "${!node}" "$i"
134 done
136 # remove empty lists
137 (( ${#tree.files[@]} == 0 )) && unset tree.files
138 (( ${#tree.dirs[@]} == 0 )) && unset tree.dirs
140 return 0
144 function pathtovartree
146 nameref tree=$1
147 typeset basedir="$2"
149 do_directory tree "${basedir}"
151 return 0
154 function usage
156 OPTIND=0
157 getopts -a "${progname}" "${filetree1_usage}" OPT '-?'
158 exit 2
161 # program start
162 builtin basename
163 builtin cat
164 builtin dirname
165 builtin date
166 builtin uname
168 typeset progname="${ basename "${0}" ; }"
170 typeset -r filetree1_usage=$'+
171 [-?\n@(#)\$Id: filetree1 (Roland Mainz) 2009-05-06 \$\n]
172 [-author?Roland Mainz <roland.mainz@sun.com>]
173 [-author?Roland Mainz <roland.mainz@nrubsig.org>]
174 [+NAME?filetree1 - file tree demo]
175 [+DESCRIPTION?\bfiletree1\b is a small ksh93 compound variable demo
176 which accepts a directory name as input, and then builds tree
177 nodes for all files+directories and stores all file attributes
178 in these notes and then outputs the tree in the format
179 specified by viewmode (either "list", "namelist", "tree" or "compacttree")..]
181 viewmode dirs
183 [+SEE ALSO?\bksh93\b(1), \bfile\b(1)]
186 while getopts -a "${progname}" "${filetree1_usage}" OPT ; do
187 # printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|"
188 case ${OPT} in
189 *) usage ;;
190 esac
191 done
192 shift $((OPTIND-1))
194 typeset viewmode="$1"
195 shift
197 if [[ "${viewmode}" != ~(Elr)(list|namelist|tree|compacttree) ]] ; then
198 fatal_error $"Invalid view mode \"${viewmode}\"."
201 typeset -C myfiletree
203 while (( $# > 0 )) ; do
204 print -u2 -f "# Scanning %s ...\n" "${1}"
205 pathtovartree myfiletree "${1}"
206 shift
207 done
208 print -u2 $"#parsing completed."
210 case "${viewmode}" in
211 list)
212 set | egrep "^myfiletree\[" | fgrep -v ']=$'
214 namelist)
215 typeset + | egrep "^myfiletree\["
217 tree)
218 print -v myfiletree
220 compacttree)
221 print -C myfiletree
224 fatal_error $"Invalid view mode \"${viewmode}\"."
226 esac
228 print -u2 $"#done."
230 exit 0
231 # EOF.