#!/bin/bash
#
# Copyright (C) 2008 Daniel Hokka Zakrisson
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.

tmp=$(getopt -o '+R:f:ut' --long root:,file:,unset,tags -n "$0" -- "$@") || {
    echo "Usage: $0 [--root <path>] [--file <file>]"
    echo "    [--unset] [--tags]"
    echo
    echo "   --root <path>   begin traversing the tree at <path>"
    echo "   --file <file>   send output to <file>"
    echo "   --unset         unset attributes after reading them"
    echo "                   WARNING: USE WITH CAUTION"
    echo "   --tags          save tags too"
    echo
    echo "Copyright (C) 2008 Daniel Hokka Zakrisson"
    echo "This program is free software; you may redistribute it under the terms of"
    echo "the GNU General Public License.  This program has absolutely no warranty."
    exit 1
} >&2
eval set -- "$tmp"

ROOT=/
FILE=
UNSET=0
TAGS=0
while true; do
    case "$1" in
	(-R|--root)	ROOT="$2"; shift;;
	(-f|--file)	FILE="$2"; shift;;
	(-u|--unset)	UNSET=1;;
	(-t|--tags)	TAGS=1;;
	(--)		shift; break;;
	(*)		echo "$0: unrecognized option: '$1'" >&2
			exit 1;;
    esac
    shift
done

set -e
export LANG=C

if test -n "$FILE"; then
    exec >"$FILE"
fi
showattr -Ra "$ROOT" | gawk '$1 ~ /[BUI]/ {
    printf "setattr ";
    unsetter="setattr ";
    if ($1 ~ /B/) {
	printf "--barrier ";
	unsetter=unsetter"--~barrier ";
    }
    if ($1 ~ /UI/) {
	printf "--iunlink ";
	unsetter=unsetter"--~iunlink ";
    }
    else if ($1 ~ /I/) {
	printf "--immutable ";
	unsetter=unsetter"--~immutable ";
    }
    else if ($1 ~ /U/) {
	printf "--iunlink-but-not-immutable ";
	unsetter=unsetter"--~iunlink-but-not-immutable ";
    }
    print $2;
    unsetter=unsetter" "$2;
    if ('$UNSET')
	system(unsetter);
}
$1 ~ /X/ && '$TAGS' {
    tmp="lsxid -nd "$2;
    tmp | getline > 0;
    printf "chxid -c %s %s\n", $1, $2;
    close(tmp);
    if ($1 != "0" && '$UNSET')
	system("chxid -c 0 "$2);
}'

exit 0

