Delete the keeper set named KEEPER.
HELP
+## Parse the command line.
case $# in 1) ;; *) usage_err ;; esac
keeper=$1
checkword "keeper set label" "$keeper"
+## Check that the set actually exists.
cd $KEYS/keeper
if [ ! -d $keeper ]; then
echo >&2 "$quis: unknown keeper set \`$keeper'"
exit 1
fi
-unset deps
+## Make sure that there aren't recovery keys which would be orphaned by
+## deleting this keeper set. Also, build a data structure of recovery keys
+## and their instances: `$recov' is a space-separated list of recovery key
+## labels, and for each such label R, `$ri_R' is a space-separated list of
+## its instances.
+unset deps; recov=" "
if [ -d $KEYS/recov ]; then
cd $KEYS/recov
- for r in $(find . -type l -name current -print); do
- r=${r#./}; r=${r%/current}
- if ! expr >/dev/null "Q$r" : "Q$R_LABEL"; then continue; fi
+
+ ## Work through the available recovery keys.
+ for r in *; do
+ if ! expr >/dev/null "Q$r" : "Q$R_WORD"; then continue; fi
+ if [ ! -l $r/current ]; then continue; fi
+
+ ## Add the key to our list.
+ recov="$recov$r "
+
+ ## Now work through the instances.
+ ii=""
for ri in $r/*; do
- i=${ri##*/}
+ i=${ri#*/}
case "$i" in *[!0-9]*) continue ;; esac
+
+ ## Add the instance to our list.
+ ii="$ii $i"
+
+ ## For each recovery key, make sure that: either it doesn't depend on
+ ## this keeper set, or it also depends on at least one other set. If
+ ## not, add it to the `deps' list.
this=nil others=nil
for kp in $r/current/*.param; do
k=${kp##*/}; k=${k%.param}
done
case $this,$others in t,nil) deps="$deps $ri" ;; esac
done
+
+ ## Record the list of instances.
+ eval "ri_$r=\$ii"
done
fi
+
+## If we found any hard dependencies, report a failure.
case "${deps+t}" in
t)
echo >&2 "$quis: deleting keeper \`$keeper' would orphan recovery keys:"
;;
esac
-if [ -d $KEYS/recov ]; then
- cd $KEYS/recov
- for r in $(find . -type l -name current -print); do
- r=${r#./}; r=${r%/current}
- if ! expr >/dev/null "Q$r" : "Q$R_LABEL"; then continue; fi
- for ri in $i/*; do
- i=${ri##*/}
- case "$i" in *[!0-9]*) continue ;; esac
- rm -f $ri/$keeper.*
- done
- changep=nil
- while read k rest; do
- case $k in $keeper) changep=t ;; *) echo "$k $rest" ;; esac
- done <$r/keepers >$r/keepers.new
- case $changep in
- t) mv $r/keepers.new $r/keepers ;;
- nil) rm $r/keepers.new ;;
- esac
- done
-fi
+## Disentangle the dependent recovery keys from this keeper set.
+for r in $recov; do
+
+ ## Remove the keeper data from the key's instances.
+ eval "ii=\$ri_$r"
+ for i in $ii; do rm -f $r/$i/$keeper.*; done
+
+ ## Work through the current keepers, and remove our keeper's name from the
+ ## list.
+ changep=nil
+ while read k rest; do
+ case $k in $keeper) changep=t ;; *) echo "$k $rest" ;; esac
+ done <$r/keepers >$r/keepers.new
+ case $changep in
+ t) mv $r/keepers.new $r/keepers ;;
+ nil) rm $r/keepers.new ;;
+ esac
+done
+## Finally, actually delete the keeper keys.
cd $KEYS/keeper
rm -r $keeper