parse_opts () {
	PARAMS=""
	CHECK=""
	PRECHECK=""
	RETRY="no"
	MAKETMP=""
	MAKESWAP=""
	USELUKS=""
	SKIP=""
	TIMEOUT=""

	# Parse the options field, convert to cryptsetup parameters
	# and contruct the command line
	while test "x$opt" != "x" ; do
		ARG=`echo $opt | sed "s/,.*//"`
		opt=${opt##$ARG}
		opt=${opt##,}
		PARAM=`echo $ARG | sed "s/=.*//"`
		
		case "$ARG" in
		  *=*)
		  	PARAM=`echo $ARG | sed "s/=.*//"`
		  	VALUE=${ARG##$PARAM=}
		  	;;
		  *)
		  	PARAM=$ARG
		  	VALUE=""
			;;
		esac
		
		case "$PARAM" in 
		  readonly)
		  	PARAMS="$PARAMS -r"
		  	;;
		  cipher)
		  	PARAMS="$PARAMS -c $VALUE"
		  	if test "x$VALUE" = "x" ; then
		  		echo -e "\n - no value for cipher option, skipping" >&2
		  		SKIP="yes"
		  	fi
		  	;;
		  size)
		  	PARAMS="$PARAMS -s $VALUE"
		  	if test "x$VALUE" = "x" ; then
		  		echo -e "\n - no value for size option, skipping" >&2
		  		SKIP="yes"
		  	fi
		  	;;
		  hash)
		  	PARAMS="$PARAMS -h $VALUE"
		  	if test "x$VALUE" = "x" ; then
		  		echo -e "\n - no value for hash option, skipping" >&2
		  		SKIP=yes
		  	fi
		  	;;
		  verify)
		  	PARAMS="$PARAMS -y"
		  	;;
		  check)
		  	if test "x$VALUE" = "x" ; then
		  		CHECK="$CRYPTDISKS_CHECK"
		  	else
		  		CHECK="$VALUE"
		  	fi
		  	if [ "$CHECK" -a -x /lib/cryptsetup/checks/"$CHECK" ]; then
		   		CHECK="/lib/cryptsetup/checks/$CHECK"
		  	else
		  		CHECK=""
		  	fi
		  	;;
		  precheck)
		  	if test "x$VALUE" = "x" ; then
		  		PRECHECK="$CRYPTDISKS_PRECHECK"
		  	else
		  		PRECHECK="$VALUE"
		  	fi
		   	if [ "$PRECHECK" -a -x /lib/cryptsetup/checks/"$PRECHECK" ]; then
		  		PRECHECK="/lib/cryptsetup/checks/$PRECHECK"
		  	else
		  		PRECHECK=""
		  	fi
		  	;;
		  retry)
		  	if test "x$VALUE" = "x" ; then
		  		RETRY="$CRYPTDISKS_RETRY"
		  	else
		  		RETRY="$VALUE"
		  	fi
		  	case "$RETRY" in
		  	  no|[0-9]*)
		  	  	;;
		  	  *)
			  	echo -e "\n - option RETRY is wrongly set to $RETRY - forced to 'no' " >&2
			  	RETRY="no"
			  	;;
			esac
		  	;;
		  timeout)
		  	if test "x$VALUE" = "x" ; then
		  		TIMEOUT="$CRYPTDISKS_TIMEOUT"
		  	else
		  		TIMEOUT="$VALUE"
		  	fi
		  	PARAMS="$PARAMS --timeout=$TIMEOUT"
		  	;;
		  swap)
		  	MAKESWAP=yes
		  	;;
		  tmp)
		  	MAKETMP=yes
		  	;;
		  luks)
		  	USELUKS=yes
			;;
		  loud)
		  	LOUD=yes
		esac
	done
}

lo_setup () {
	# Set up loopback devices
	if test -f "$src" ; then
		test -d /sys/block/loop0 || modprobe loop || SKIP=yes
		LOOP_ID=
		for i in 0 1 2 3 4 5 6 7 ; do
			if test "x`cat /sys/block/loop$i/size`" = "x0" ; then
				LOOP_ID=$i
				break
			fi
		done
		if test "x$LOOP_ID" = "x" ; then
			SKIP=yes
		else
			$LOSETUP /dev/loop$LOOP_ID $src || SKIP=yes
			src=/dev/loop$LOOP_ID
		fi
	fi
}

check_key () {
	if [ "x$key" != "x" ] && [ "x$key" != "xnone" ]; then
		INTERACTIVE="no"
		if test -e "$key" ; then
			MODE=`ls -l $key | sed 's/^....\(......\).*/\1/'`
			OWNER=`ls -l $key | sed 's/^[^ ]* *[^ ]* *\([^ ]*\).*/\1/'`

			# luks requires a persistent key, /dev/*random is not supported
			if test "x$USELUKS" == "xyes"; then
				if test "$key" == "/dev/urandom" || \
				   test "$key" == "/dev/hwrandom" || \
				   test "$key" == "/dev/random"; then
					echo -e "\n - LUKS does not work with a random data key, skipping" >&2
					continue
				fi
			fi
			if test "$MODE" != "------" && \
			   test "$key" != "/dev/urandom"  && \
			   test "$key" != "/dev/hwrandom" && \
			   test "$key" != "/dev/random"; then
				echo -e "\n - INSECURE MODE FOR $key" >&2
			fi
			if test $OWNER != root; then
				echo -e "\n - INSECURE OWNER FOR $key" >&2
			fi
		else
			echo -e "\n - Keyfile for '$dst' not found, skipping" >&2
			continue
		fi
	else
		INTERACTIVE="yes"
		echo ""
	fi
}

do_luks () {
	if $CRYPTCMD isLuks $src >/dev/null 2>&1; then
		while [ "x$RETRY" = xno ]  || [ "$RETRY" -gt 0 ] ; do
			if test "x$INTERACTIVE" = "xyes" ; then
				$CRYPTCMD $PARAMS luksOpen $src $dst <&1
				RESULT=$?
			else
				$CRYPTCMD $PARAMS luksOpen $src $dst --key-file $key <&1
				RESULT=$?
			fi
			if [ $RESULT = 0 ] ; then
				if [ "$CHECK" = ""  ] || $CHECK $MAPPER/$dst ; then
					break
				else
					echo -e "\n - the check for '$MAPPER/$dst' failed" >&2
					#echo " - removing the crypto device $dst" >&2
					#$CRYPTCMD luksClose $dst
					sleep 1
				fi
			fi
			test "x$RETRY" = "xno" && break
			RETRY=$(($RETRY-1))
			[ $RETRY -gt 0 ] && echo " - retrying for $dst"
		done
	else
		echo -e "\n - Device '$src' is not a LUKS partition, skipping" >&2
		continue
	fi
}

do_noluks () {
	if [ "$PRECHECK" = "" ] || $PRECHECK $src; then
		while [ "x$RETRY" = xno ]  || [ "$RETRY" -gt 0 ] ; do
			if test "x$INTERACTIVE" = "xyes" ; then
				$CRYPTCMD $PARAMS create $dst $src <&1
				RESULT=$?
			else
				$CRYPTCMD $PARAMS -d $key create $dst $src
				RESULT=$?
			fi
			if [ $RESULT = 0 ] ; then
				if [ "$CHECK" = ""  ] || $CHECK $MAPPER/$dst ; then
					break
				else
					echo -e "\n - the check for '$MAPPER/$dst' failed - maybe the password is wrong" >&2
					echo " - removing the crypto device $dst" >&2
					$CRYPTCMD remove $dst
					sleep 1
				fi
			fi
			test "x$RETRY" = "xno" && break
			RETRY=$(($RETRY-1))
			[ $RETRY -gt 0 ] && echo " - retrying for $dst"
		done
	else
		echo -e "\n - the precheck for '$src' failed" >&2
		sleep 1
	fi
}

do_swap () {
	if test "x$MAKESWAP" = "xyes" && test -b $MAPPER/$dst; then
		mkswap $MAPPER/$dst 2>/dev/null >/dev/null
	fi
}

do_tmp () {
	if test "x$MAKETMP" = "xyes" && test -b $MAPPER/$dst; then
		mke2fs $MAPPER/$dst >/dev/null
		mount -t ext2 $MAPPER/$dst /tmp
		chmod 1777 /tmp
		umount /tmp
	fi
}
