#!/bin/bash
#
# btrfs-superblock-delete
#
# (c)2013 Marek Uher <marek@uher.info>
#
# Wipe a btrfs file system signature from a device
#

NO_ERROR=0
ERROR_INVALID_ARGUMENTS=1
ERROR_INVALID_OPTION=2
ERROR_INVALID_DEVICE=3
ERROR_INVALID_SUPERBLOCK=4
ERROR_INVALID_SUPERBLOCK_OFFSET=5
ERROR_USER_ABORT=6

ERROR_CODE=${NO_ERROR}
FORCE="no"

print_version() {

	echo "btrfs-superblock-delete v0.1"
	echo "(c)2013 Marek Uher <marek@uher.info>"
}

print_help() {

	echo ""
	print_version
	echo ""
	echo "btrfs-superblock-delete can erase btrfs file system signatures (magic strings)"
	echo "from the specified device to make the file system invisible for libblkid and"
	echo "btrfs command. btrfs-superblock-delete does not erase the file system itself"
	echo "nor any other data from the device."
	echo ""
	echo "usage:   btrfs-superblock-delete [option] dev"
	echo ""
	echo "option:  -h | --help      will print this description"
	echo "         -f | --force     will try to erase btrfs file system signatures"
	echo "                          directly using dd (instead of executing wipefs"
	echo "                          command only), warning - proceed with caution"
	echo ""
	echo "dev:     any block (disk) device (partition)"
	echo ""
	echo "example: btrfs-superblock-delete --force /dev/sda8"
	echo ""
}

print_usage() {

	echo "usage: btrfs-superblock-delete [option] dev"
	echo "type btrfs-superblock-delete --help for more information"
}

wrong_arguments() {

	echo "missing one or more argument(s)"
	print_usage
}

wrong_option() {

	echo "unrecognized option '$1'"
	print_usage
}

wrong_device() {

	echo "wrong block device '$1'"
	print_usage
}

case $# in

	1)
		if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then

			print_help
			exit ${NO_ERROR} 

		else

			DEVICE=$1

		fi
		;;

	2)
		OPTION=$1
		DEVICE=$2

		if [ ! "${OPTION}" == "-f" ] && [ ! "${OPTION}" == "--force" ]; then

			wrong_option ${OPTION}
			exit ${ERROR_INVALID_OPTION}

		else

			FORCE="yes"

		fi
		;;

	*)
		wrong_arguments
		exit ${ERROR_INVALID_ARGUMENTS}
		;;
esac

if [ -b ${DEVICE} ] && [ "${DEVICE}" != "" ]; then

	OFFSET=`wipefs ${DEVICE} | awk '/^0x/{ print $1 }'`
	FILESYSTEM=`wipefs ${DEVICE} | awk '/^0x/{ print $2 }'`
	UUID=`wipefs ${DEVICE} | awk '/^ /{ print $2 }'`

	if [ "${FILESYSTEM}" != "btrfs" ] && [ "${FORCE}" == "no" ]; then
		echo "unable to locate valid btrfs superblock on device ${DEVICE}"
		exit ${ERROR_INVALID_SUPERBLOCK} 
	fi 

	if [ "${OFFSET}" == "" ] && [ "${FORCE}" == "no" ]; then
		echo "unable to determine superblock offset on device ${DEVICE}"
		exit ${ERROR_INVALID_SUPERBLOCK_OFFSET}
	fi
	
	if [ "${FILESYSTEM}" == "" ]; then
		FILESYSTEM="<NULL>"
	fi
	
	if [ "${UUID}" == "" ]; then
		UUID="<NULL>"
	fi

	echo "are you sure to remove superblock for ${FILESYSTEM} file system with active"
	echo "UUID ${UUID} on device ${DEVICE} [y/n]?"

	read ANSWER

	if [ ! "${ANSWER}" == "y" ] && [ ! "${ANSWER}" == "Y" ]; then
		echo "exiting without any further action"
		exit ${ERROR_USER_ABORT} 
	fi

	wipefs -o ${OFFSET} ${DEVICE} > /dev/null 2>&1
	ERROR_CODE=$?

	if [ "${ERROR_CODE}" != "0" ] && [ "${FORCE}" == "no" ]; then

		echo "wipefs failed with error code ${ERROR_CODE}"
		exit ${ERROR_CODE}

	fi

	if [ "${FORCE}" == "yes" ]; then

		dd if=/dev/zero bs=1 count=8 of=${DEVICE} seek=$((64*1024+64)) > /dev/null 2>&1
		ERROR_CODE=$?

		if [ "${ERROR_CODE}" != "0" ]; then

			echo "the first call of dd failed with error code ${ERROR_CODE}"
			exit ${ERROR_CODE}

		fi

		dd if=/dev/zero bs=1 count=8 of=${DEVICE} seek=$((64*1024*1024+64)) > /dev/null 2>&1
		ERROR_CODE=$?

		if [ "${ERROR_CODE}" != "0" ]; then

			echo "the second call of dd failed with error code ${ERROR_CODE}"
			exit ${ERROR_CODE}

		fi

		dd if=/dev/zero bs=1 count=8 of=${DEVICE} seek=$((256*1024*1024*1024+64)) > /dev/null 2>&1
		ERROR_CODE=$?

		if [ "${ERROR_CODE}" != "0" ]; then

			echo "the third call of dd failed with error code ${ERROR_CODE}"
			exit ${ERROR_CODE}

		fi

	fi

	echo "system signatures (magic strings) are successfully wiped out from"
	echo "device ${DEVICE}"
	exit ${ERROR_CODE}
else

	wrong_device ${DEVICE}
	exit ${ERROR_INVALID_DEVICE}
fi

# /* End of file: btrfs-superblock-delete */
