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