#! /bin/sh -u
# @(#)writersfix $Revision: 1.5 $ $Date: 93/01/20 13:11:24 $ $State: Released $
#
# Script to remove _writers from the specified directory and its
# children.

PATH=/usr/bin:/bin:/usr/ucb:/usr/etc:/etc:. export PATH
TEMP=/tmp/wf.$$

PGMNAME=`basename $0`
DEFAULT_Verbose=true
DEFAULT_vFlag=
DEFAULT_Remove=false
DEFAULT_rFlag=
DEFAULT_Recursive=false
DEFAULT_RFlag=
DEFAULT_Sp=""
DEFAULT_Domain=/
DEFAULT_Directory=/printers

# We use -remove (rather than just -r) to help avoid confusion
# between -r (remove) and -R (recurse).
USAGE="${PGMNAME} [-s] [-R] [-remove] [-d directory] [domain]"
DESCRIPTION="\
	-s	Silent
	-R	Recurse through NetInfo domain hierarchy
	-remove	Remove _writers (default is just show)
	-d directory	Directory to check (default: $DEFAULT_Directory)
	domain	Domain to check (default: $DEFAULT_Domain)
The specified directory and its immediate subdirectories are checked.
If -R is used, the domain must be specified as a full path, not a
relative domain name."

E_OK=0
E_Syntax=2
E_BadDomain=3
E_NIError=4
E_FoundWriters=5

# Proceess arguments
while [ $# -gt 0 ]; do
    case ${1} in
    -help | -Help | -HELP)	# Help the user
	echo "$USAGE"
	echo "$DESCRIPTION"
	exit $E_OK
	;;
    -s)	# Silent
	Verbose=false
	vFlag=-s
	;;
    -R)	# Recursive: apply to all child domains
	Recursive=true
	RFlag=-R
	Sp="    "
	;;
    -remove)	# Remove the _writers property
	Remove=true
	rFlag=-remove
	;;
    -d)	# Specify the directory to examine
	if [ 2 -ge $# ]; then
	    echo 1>&2 "${PGMNAME}: missing argument to -d"
	    exit $E_Syntax
	fi
	Directory="${2}"
	shift
	;;
    -*)	# Error
	echo 1>&2 "${PGMNAME}: unknown flag $1"
	echo 1>&2 "Usage: $USAGE"
	exit $E_Syntax
	;;
    *)	# Domain name
	Domain="${1}"
	;;
    esac
    shift
done

Verbose="${Verbose-$DEFAULT_Verbose}"
vFlag="${vFlag-$DEFAULT_vFlag}"
Remove="${Remove-$DEFAULT_Remove}"
rFlag="${rFlag-$DEFAULT_rFlag}"
Recursive="${Recursive-$DEFAULT_Recursive}"
RFlag="${RFlag-$DEFAULT_RFlag}"
Sp="${Sp-$DEFAULT_Sp}"
Domain="${Domain-$DEFAULT_Domain}"
Directory="${Directory-$DEFAULT_Directory}"

# If recursive, can't handle relative domain names!
if $Recursive; then
    case "${Domain}" in
    /*)	# Full path: ok
	;;
    .*)	# Relative path: no go
	echo 1>&2 "Cannot specify relative domain names with recursive option."
	exit $E_BadDomain
	;;
    *)	# Something's weird, here
	echo 1>&2 "Illegal domain name (starts with neither / nor .)"
	exit $E_BadDomain
	;;
    esac
fi

if $Remove; then
    Operation="removed"
else
    Operation="found"
fi

FoundWriters=false

# First, handle the domain specified.  Examine the directory first
if $Verbose; then
    if $Recursive; then
	echo "Domain ${Domain}"
    fi
    echo -n "${Sp}${Domain}:${Directory} "
fi
niutil -read ${Domain} ${Directory} 2> /dev/null | bm -s _writers
if [ 0 -eq $? ]; then
    # Directory has an _writers
    RetCode=$E_FoundWriters
    if $Remove; then
	niutil -destroyprop ${Domain} ${Directory} _writers 2> /dev/null
    fi
    if [ 0 -ne $? ]; then
	RetCode=$E_NIError
	echo 1>&2 "couldn't remove _writers from ${Domain}:${Directory}"
    elif $Verbose; then
	echo "$Operation _writers"
    fi
elif $Verbose; then
    echo ""
fi

# Now, examine the directory's subdirectories.  We iterate over
# the directory numbers, and then translate things below, to
# protect against directories with slashes in their names (like the
# subdirectories of /mounts).
for dirnum in `niutil -list ${Domain} ${Directory} 2> /dev/null | \
	awk '{print $1}'`; do
    SubDir=`niutil -read ${Domain} ${dirnum} | \
	awk '/^name:/	{printf "%s", $2}'`
    if $Verbose; then
	echo -n "${Sp}${Domain}:${Directory}/${SubDir} [${dirnum}] "
    fi
    niutil -read ${Domain} ${dirnum} 2> /dev/null | bm -s "_writers:"
    if [ 0 -eq $? ]; then
	# Directory has an _writers
	RetCode=$E_FoundWriters
	if $Remove; then
	    niutil -destroyprop ${Domain} ${dirnum} _writers 2> /dev/null
	fi
	if [ 0 -ne $? ]; then
	    RetCode=$E_NIError
	    echo 1>&2 \
"couldn't remove _writers from ${Domain}:${Directory}/${SubDir} [${dirnum}]"
	    continue
	elif $Verbose; then
	    echo -n "$Operation _writers"
	fi
    fi
    if $Verbose; then
	echo ""
    fi
done

if $Recursive; then
    # Examine ${Domain}'s child domains, recursively.  Get all the serves
    # properties, then turn those into domain names.
    niutil -list ${Domain} /machines serves > $TEMP 2> /dev/null
    if [ 0 -ne $? ]; then
	echo 1>&2 "Could not contact ${Domain}"
    else
	# The serves properties are in $TEMP; turn them into domain names.
	awk -f - > $TEMP.1 $TEMP << \Writers!Fix
{for (i = 2; i <= NF; i++) \
    {len = index($i, "/") - 1
     if (0 == len) \
	{printf "%s ", $i}
     else
	{printf "%s ", substr($i, 1, len)}}}
Writers!Fix
    
	# Iterate over the child domains
	for child in `cat $TEMP.1`; do
	    if [ "." != "$child" -a ".." != "$child" ]; then
		$0 $vFlag $RFlag $rFlag -d "${Directory}" "${Domain}/${child}"
		case $? in
		$E_OK)	# No errors, not found
		    ;;
		$E_Syntax | $E_BadDomain)	# We blew our call
		    RetCode=$?
		    echo 1>&2 "Problem invoking $0 [$RetCode]"
		    exit $RetCode
		    ;;
		$E_NIError)	# NetInfo error
		    RetCode=$?
		    ;;
		$E_FoundWriters)	# Found an _writers
		    RetCode=$E_FoundWriters
		    ;;
		*)	# Shell problem, or something's weird
		    RetCode=$?
		    echo 1>&2 "Unexpected return from $0 [$RetCode]"
		    exit $RetCode
		    ;;
		esac
	    fi
	done
    fi
fi

rm -f $TEMP $TEMP.1

exit ${RetCode-$E_OK}
