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