X-Git-Url: https://git.distorted.org.uk/~mdw/distorted-keys/blobdiff_plain/a218eb121bc640b2821aa21f208f082881b7fc29..aa8478931ce8fa13b56f260da29241f38c18ab76:/keys.delete-keeper diff --git a/keys.delete-keeper b/keys.delete-keeper index 1e3f3ec..908e22e 100755 --- a/keys.delete-keeper +++ b/keys.delete-keeper @@ -32,34 +32,61 @@ KEEPER 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 + for kp in $ri/*.param; do k=${kp##*/}; k=${k%.param} case $k in $keeper) this=t ;; *) others=t ;; esac 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:" @@ -68,27 +95,26 @@ case "${deps+t}" in ;; 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