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

	# Parse the options field, convert to cryptsetup parameters
	# and construct 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
			;;
		  ssl)
		  	SSL=yes
			;;
		  gpg)
		  	GPG=yes
			;;
		esac
	done

	if [ "$SSL" != "" -a "$GPG" != "" ]; then
		echo -e "\n - ssl and gpg options are not allowed together, skipping" >&2
		continue
	fi
}

decrypt_ssl () {
	origumask=`umask`
	umask 077
	tmpkey=`tempfile`

	while ( ! /usr/bin/openssl enc -aes256 -d -salt -in $key -out $tmpkey \
	          -k $password > /dev/null 2>&1 ); do
		echo -en "\nSecond password for key $key: "
		read -s password <${CONSOLE:-/dev/tty}
		echo
		[ "$password" = "" ] && return 0
	done

	deckey=`tempfile`
	while ( ! /usr/bin/openssl dsa -in $tmpkey -out $deckey -passin \
	          pass:$password > /dev/null 2>&1 ); do
		echo -en "\nFirst password for key $key: "
		read -s password <${CONSOLE:-/dev/tty}
		echo
		[ "$password" = "" ] && return 0
	done

	password=""
	rm -f $tmpkey && tmpkey=""
	umask $origumask
}

decrypt_gpg () {
	origumask=`umask`
	umask 077
	deckey=`tempfile`

	echo -e "\n - gpg option is not implemented yet, skipping" >&2
	continue

	while ( ! echo $password | /usr/bin/gpg --passphrase-fd 0 -o $deckey \
	          --decrypt $key >/dev/null 2>&1 ); do
		echo -en "\nPassphrase for key $key: "
		read -s password <${CONSOLE:-/dev/tty}
		echo
		[ "$password" = "" ] && return 0
	done
	
	password=""
	umask $origumask
}

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 random data as 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
		if [ "x$SSL" = "xyes" ]; then
			if [ -x /usr/bin/openssl ]; then
				decrypt_ssl && key=$deckey
			else
				echo -e "\n - Openssl isnot available, skipping" >&2
				continue
			fi
		elif [ "x$GPG" = "xyes" ]; then
			if [ -x /usr/bin/gnupg ]; then
				decrypt_gpg && key=$deckey
			else
				echo -e "\n - Gnupg is not available, skipping" >&2
				continue
			fi
		fi
	else
		INTERACTIVE="yes"
		[ -x /sbin/usplash_write ] && /sbin/usplash_write "QUIT"
		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
}

clean_keys () {
	if [ "$deckey" -a -f "$deckey" ]; then
	  rm -f $deckey && deckey=""
	fi
}
