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