summaryrefslogtreecommitdiffstats
path: root/shop
diff options
context:
space:
mode:
authorFlorian Pritz <bluewind@xssn.at>2010-08-08 22:51:46 +0200
committerFlorian Pritz <bluewind@xssn.at>2010-08-08 22:51:46 +0200
commit176f5e0c0e6730908f35aebf60a1e33f8735a025 (patch)
tree879c10b997aa124ea8771bdfb4e09c93f52a6871 /shop
parentd2754512c34a19dad7e489b97fd80bf0bd634089 (diff)
downloadbin-176f5e0c0e6730908f35aebf60a1e33f8735a025.tar.gz
bin-176f5e0c0e6730908f35aebf60a1e33f8735a025.tar.xz
add 3 more files
Signed-off-by: Florian Pritz <bluewind@xssn.at>
Diffstat (limited to 'shop')
-rwxr-xr-xshop157
1 files changed, 157 insertions, 0 deletions
diff --git a/shop b/shop
new file mode 100755
index 0000000..c2e01fe
--- /dev/null
+++ b/shop
@@ -0,0 +1,157 @@
+#!/bin/bash
+#
+# shop - Show Permissions at all levels of a given path
+#
+# With `tree(1)` you start at a trunk and show all leaves that
+# originate from that trunk, optionally showing permissions.
+# `shop` starts at a leaf and shows the permissions back to a
+# trunk.
+#
+# CREATED: 2009-09-03 17:30
+# MODIFIED: 2009-11-17 11:05
+
+_NAME=$(basename $0)
+_VERSION=1.0
+
+# DEFAULTS
+unset octal # use text mode instead of octal mode
+level=-1 # traverse all the way up to /
+trunk='/' # traverse all the way up to /
+pad=17 # padding for pathname
+
+usage() {
+ cat <<EOT
+Usage: $_NAME [-L N] [-o] [-t PATH] [PATH1..]
+
+Options:
+ -L, --level N traverse N levels up the tree
+ -o, --octal show octal mode instead of human readable mode
+ -t, --trunk PATH only traverse up to PATH instead of / (root)
+ - takes precedence over --level
+ -p, --pad N allow USER:GROUP N characters before directory name
+ default: 17
+
+ -h, --help show this message
+ --version show version info
+EOT
+}
+
+_shop() {
+ [ $octal ] && stat_str="%a" || stat_str="%A"
+
+ stats=( $(stat -c "$stat_str %U:%G %n" "$1") )
+
+ if [ $octal ]; then
+ # `stat -c "%a"` only returns a 4 digit mode when the first digit is
+ # nonzero, yet `stat` always returns a 4 digit mode. how annoying...
+ [ ${#stats} -eq 3 ] && echo -n "0"
+ fi
+
+ printf "%s %-${pad}s ${stats[@]:2}\n" "${stats[@]:0:2}"
+}
+
+main() {
+ arg="$1"
+ if [ -z "$arg" ]; then
+ # user didn't supply an arg, use current working dir
+ arg="$PWD"
+ fi
+
+ until [ -z "$arg" ]; do
+ if ! [ -a "$arg" ]; then
+ echo "error: $arg does not exist"
+ return 1
+ fi
+
+ # if $arg is a directory, prime the directory stack, else use
+ # the parent dir of $arg to prime the stack
+ if [ -d "$arg" ]; then
+ cd "$arg" || return 1
+ unset file_arg
+ else
+ cd $(dirname -- "$arg") || return 1
+ file_arg=1
+ let "level -=1"
+ fi
+
+ start_dir=$PWD
+
+ # populate directory stack with $level levels on the path to
+ # the $trunk
+ while [ "$PWD" != "$trunk" ]; do
+ if [ $level -gt 0 ] || [ $level -lt 0 ]; then
+ let "level -= 1"
+ pushd .. &> /dev/null
+ elif [ $level -eq 0 ]; then
+ break;
+ fi
+ done
+
+ # display the permissions for each level
+ while [ "$PWD" != "$start_dir" ]; do
+ _shop "$PWD"
+ popd &> /dev/null
+ done
+ _shop "$PWD"
+
+ # leaf was a file, run _shop on this file as well
+ if [ $file_arg ]; then
+ _shop "${PWD}/$(basename -- "$arg")"
+ else
+ cd .. || return 1
+ fi
+
+ # user passed multiple leafs, separate output for each leaf
+ if [ $# -gt 1 ]; then
+ echo
+ fi
+
+ shift
+ arg="$1"
+ done
+}
+
+declare -a args
+until [ -z "$1" ]; do
+ case "$1" in
+ -L|--level) level="$2"
+ shift 2
+ ;;
+
+ -o|--octal) octal=1
+ shift
+ ;;
+
+ -t|--trunk) trunk="$(readlink -f $2)"
+ shift 2
+ ;;
+
+ -p|--pad) pad="$2"
+ shift 2
+ ;;
+
+ -h|--help) usage
+ exit
+ ;;
+
+ --version) echo "$_NAME v$_VERSION"
+ exit
+ ;;
+
+ --) shift
+ args=( "${args[@]}" "$@" )
+ break
+ ;;
+
+ -*) echo -e "$_NAME: unknown option: $1\n"
+ usage
+ exit
+ ;;
+
+ *) args[${#args[*]}]="$1"
+ shift
+ ;;
+ esac
+done
+
+main "${args[@]}"