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