#!/bin/bash # $HeadURL$ $LastChangedRevision$ # Modules . $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; } . <(rdw2-config --format=shell) || { echo "${0##*/}: INTERNAL ERROR: failed to run rdw2-config" >&2; exit 3; } # Configurable stuff # Other globals main() { local MY_ARGS local MODE LABEL_TYPE LABELEE EXECER EXPANDED_TEMPLATE LABEL_FILE ESCAPED_LABELEE PROGNAME # Defaults for options HOST= FORCE_FLAG=false TEMPLATE=".rdw2-%{LABEL_TYPE}-label" REROOT_DIR=${LABEL_TOOL_REROOT_DIR:-unset} REROOT_FLAG=${LABEL_TOOL_REROOT_FLAG:-unset} # Process options special_opts_handler() { case $1 in --host=*) HOST=${1#*=} ;; --reroot) REROOT_FLAG=true ;; --no-reroot) REROOT_FLAG=false ;; --reroot-dir=*) REROOT_DIR=${1#*=} ;; --force) FORCE_FLAG=true ;; --template=*) TEMPLATE=${1#*=} ;; *) return 1 ;; esac } miniade_process_options --help-handler=help --special-opts-handler=special_opts_handler MY_ARGS "$@" && set -- "${MY_ARGS[@]}" # Process arguments [ $# -ge 3 ] || miniade_bad_usage MODE=$1 LABEL_TYPE=$2 LABELEE=$3 shift 3 # Sanity checks and derivations miniade_get_progname PROGNAME [ "X$REROOT_DIR" != Xunset ] || REROOT_DIR=$HOME/.$PROGNAME [[ $MODE =~ ^(add|verify|is-labelled|read|delete|touch)$ ]] || miniade_bad_usage [[ $LABEL_TYPE =~ ^(medium|client|server|session|dle)$ ]] || miniade_bad_usage if [ "X$HOST" != X ]; then EXECER="ssh -T $HOST" else EXECER="bash" fi if [ "X$($EXECER <<<"echo OK" 2>&1)" != XOK ]; then miniade_error "$EXECER: couldn't run (hint: see messages above)" fi if ! [[ $LABELEE =~ ^/ ]]; then miniade_error "$LABELEE: not absolute (hint: must be absolute!)" fi if ! $EXECER <<<"[ -d $LABELEE ]"; then miniade_error "$LABELEE: no such directory (hint: you must create it yourself)" fi if [ $REROOT_FLAG != unset ]; then : elif [ -w / ]; then REROOT_FLAG=false #elif [ "X$LABEL_TOOL_QUIET" != X ]; then # REROOT_FLAG=true else miniade_warning "you are not root; a fake root hierarchy will be used for labels" REROOT_FLAG=true fi EXPANDED_TEMPLATE=$(expand "$TEMPLATE") if $REROOT_FLAG; then ESCAPED_LABELEE=$(escape "$LABELEE") LABEL_FILE=$REROOT_DIR/$ESCAPED_LABELEE.${EXPANDED_TEMPLATE#.} mkdir -p $REROOT_DIR # Treat / specially, so that LABEL_FILE doesn't get double leading /. elif [ "X$LABELEE" = X/ ]; then LABEL_FILE=/$EXPANDED_TEMPLATE else LABEL_FILE=$LABELEE/$EXPANDED_TEMPLATE fi miniade_debug 10 "main: LABEL_FILE=$LABEL_FILE" # Guts # (delegated) mode_${MODE//-/_} "$@" } help() { local PROGNAME miniade_get_progname PROGNAME echo "Usage: $PROGNAME [ ] add " echo " $PROGNAME [ ] verify " echo " $PROGNAME [ ] is-labelled " echo " $PROGNAME [ ] read " echo " $PROGNAME [ ] delete " echo " $PROGNAME [ ] touch " echo echo ": client, dle, medium, session" echo exit 0 } mode_add() { local DESIRED_LABEL PROGNAME VERBOSELEVEL # Process arguments [ $# = 1 ] || miniade_bad_usage DESIRED_LABEL=$1 # Sanity checks and derivations [[ $DESIRED_LABEL =~ ^.{8}-.{4}-.{4}-.{4}-.{12}$ ]] || miniade_error "$DESIRED_LABEL: invalid label (hint: run 'uuidgen' to see what valid labels look like)" miniade_get_progname PROGNAME miniade_get_verboselevel VERBOSELEVEL # Guts $EXECER < <( echo '. $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; }' echo "miniade_set_verboselevel $VERBOSELEVEL" echo "miniade_set_progname $PROGNAME" echo "[ -d \"\$(dirname \"$LABEL_FILE\")\" ] || miniade_error \"$LABEL_FILE: parent directory is not accessible (hint: is the path really correct?)\"" if $FORCE_FLAG; then echo "[ -h $LABEL_FILE -o -e $LABEL_FILE ] && miniade_warning \"$LABEL_TYPE is already labelled but '--force' specified\"" else echo "[ -h $LABEL_FILE -o -e $LABEL_FILE ] && miniade_error \"$LABEL_TYPE is already labelled\"" fi echo "echo $DESIRED_LABEL > $LABEL_FILE" ) } mode_verify() { local EXPECTED_LABEL PROGNAME VERBOSELEVEL # Process arguments [ $# = 1 ] || miniade_bad_usage EXPECTED_LABEL=$1 # Sanity checks and derivations [[ $EXPECTED_LABEL =~ ^.{8}-.{4}-.{4}-.{4}-.{12}$ ]] || miniade_error "$EXPECTED_LABEL: invalid label (hint: run 'uuidgen' to see what valid labels look like)" miniade_get_progname PROGNAME miniade_get_verboselevel VERBOSELEVEL # Guts $EXECER < <( echo '. $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; }' echo "miniade_set_verboselevel $VERBOSELEVEL" echo "miniade_set_progname $PROGNAME" echo "ACTUAL_LABEL=\"\$(cat $LABEL_FILE 2>&1)\"" echo "[ \"X\$ACTUAL_LABEL\" = \"X$EXPECTED_LABEL\" ] || miniade_error \"$LABEL_TYPE has wrong label (expected: $EXPECTED_LABEL; found: \$ACTUAL_LABEL)\"" ) } mode_is_labelled() { local PROGNAME VERBOSELEVEL # Process arguments [ $# = 0 ] || miniade_bad_usage # Sanity checks and derivations miniade_get_progname PROGNAME miniade_get_verboselevel VERBOSELEVEL # Guts $EXECER < <( echo '. $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; }' echo "miniade_set_verboselevel $VERBOSELEVEL" echo "miniade_set_progname $PROGNAME" echo "[ -f $LABEL_FILE ] || miniade_error \"$LABEL_TYPE: not labelled\"" echo "ACTUAL_LABEL=\$(cat $LABEL_FILE)" echo "[[ \$ACTUAL_LABEL =~ ^.{8}-.{4}-.{4}-.{4}-.{12}\$ ]] || miniade_error \"$LABEL_TYPE: has corrupted label\"" ) } mode_read() { local PROGNAME VERBOSELEVEL # Process arguments [ $# = 0 ] || miniade_bad_usage # Sanity checks and derivations miniade_get_progname PROGNAME miniade_get_verboselevel VERBOSELEVEL # Guts $EXECER < <( echo '. $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; }' echo "miniade_set_verboselevel $VERBOSELEVEL" echo "miniade_set_progname $PROGNAME" echo "cat $LABEL_FILE" ) } mode_delete() { local EXPECTED_LABEL PROGNAME VERBOSELEVEL # Process arguments [ $# = 1 ] || miniade_bad_usage EXPECTED_LABEL=$1 # Sanity checks and derivations miniade_get_progname PROGNAME miniade_get_verboselevel VERBOSELEVEL # Guts $EXECER < <( echo '. $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; }' echo "miniade_set_verboselevel $VERBOSELEVEL" echo "miniade_set_progname $PROGNAME" echo "ACTUAL_LABEL=\"\$(cat $LABEL_FILE 2>&1)\"" echo "[ \"X\$ACTUAL_LABEL\" = \"X$EXPECTED_LABEL\" ] || miniade_error \"$LABEL_TYPE has wrong label (expected: $EXPECTED_LABEL; found: \$ACTUAL_LABEL)\"" echo "miniade_debug 10 \"deleting $LABEL_TYPE label ${HOST:+on $HOST }...\"" echo "rm $LABEL_FILE" ) } mode_touch() { local EXPECTED_LABEL PROGNAME VERBOSELEVEL # Process arguments [ $# = 1 ] || miniade_bad_usage EXPECTED_LABEL=$1 # Sanity checks and derivations miniade_get_progname PROGNAME miniade_get_verboselevel VERBOSELEVEL # Guts $EXECER < <( echo '. $(miniade) || { echo "${0##*/}: ERROR: miniade failed (hint: run 'miniade' to see error)" >&2; exit 1; }' echo "miniade_set_verboselevel $VERBOSELEVEL" echo "miniade_set_progname $PROGNAME" echo "ACTUAL_LABEL=\"\$(cat $LABEL_FILE 2>&1)\"" echo "[ \"X\$ACTUAL_LABEL\" = \"X$EXPECTED_LABEL\" ] || miniade_error \"$LABEL_TYPE has wrong label (expected: $EXPECTED_LABEL; found: \$ACTUAL_LABEL)\"" echo "touch $LABEL_FILE" ) } escape() { local THING=$1 THING=${THING//%/%25} THING=${THING//\//%2f} THING=${THING// /%20} echo "$THING" } expand() { local THING=$1 THING=${THING//%\{LABEL_TYPE\}/$LABEL_TYPE} echo "$THING" } main "$@"