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

BTRFS_SIGNATURE="_BHRfS_M"

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}

print_version() {

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

print_help() {

	echo ""
	print_version
	echo ""
	echo "btrfs-superblock-restore can try to restore btrfs file system signatures (magic"
	echo "strings) on the specified device to make the file system visible again for"
	echo "libblkid and btrfs command." 
	echo ""
	echo "usage:   btrfs-superblock-restore dev"
	echo ""
	echo "option:  -h | --help      will print this description"
	echo ""
	echo "dev:     any block (disk) device (partition)"
	echo ""
	echo "example: btrfs-superblock-restore /dev/sda8"
	echo ""
}

print_usage() {

	echo "usage: btrfs-superblock-restore dev"
	echo "type btrfs-superblock-restore --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
		;;

	*)
		wrong_arguments
		exit ${ERROR_INVALID_ARGUMENTS}
		;;
esac

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

	echo "are you sure to restore superblock for btrfs file system on"
	echo "device ${DEVICE} [y/n]?"

	read ANSWER

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


	echo "${BTRFS_SIGNATURE}" | dd 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

	echo "${BTRFS_SIGNATURE}" | dd 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

	echo "${BTRFS_SIGNATURE}" | dd 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


	echo "system signatures (magic strings) are successfully restored on"
	echo "device ${DEVICE}"
	exit ${ERROR_CODE}
else

	wrong_device ${DEVICE}
	exit ${ERROR_INVALID_DEVICE}
fi

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