Split out reading /etc/crypttab and procssing the individual lines into
their own helper functions, and bashify the resulting shorter code.

Processing this file is still ugly, though. :(
---
 functions   |   43 +++++++++++++++++--
 rc.shutdown |   36 +++++------------
 rc.sysinit  |  131 ++++++++++++++++++----------------------------------------
 3 files changed, 90 insertions(+), 120 deletions(-)

diff --git a/functions b/functions
index bf6ed45..9ec8b5e 100644
--- a/functions
+++ b/functions
@@ -232,6 +232,40 @@ kill_everything() {
     run_hook single_postkillall
 }
 
+activate_vgs() {
+    [[ $USELVM =~ yes|YES && -x /sbin/lvm && -d /sys/block ]] || return
+    # Kernel 2.6.x, LVM2 groups
+    /sbin/modprobe -q dm-mod 2>/dev/null
+    stat_busy "Activating LVM2 groups"
+    if /sbin/lvm vgchange --ignorelockingfailure -a y >/dev/null; then
+       stat_done
+    else
+       stat_fail
+     fi
+}
+
+# Arch cryptsetup packages traditionally contained the binaries
+#  /usr/sbin/cryptsetup
+#  /sbin/cryptsetup.static
+# By default, initscripts used the /sbin/cryptsetup.static.
+# Newer packages will only have /sbin/cryptsetup and no static binary
+# This ensures maximal compatibility with the old and new layout
+for CS in /sbin/cryptsetup /usr/sbin/cryptsetup \
+    /sbin/cryptsetup.static ''; do
+    [[ -x $CS ]] && break
+done
+
+read_crypttab() {
+    # $1 = function to call with the split out line from the crypttab
+    local line nspo failed=0
+    while read line; do
+        [[ $line && ${line:0:1} != '#' ]] || continue
+        eval nspo=("${line%#*}")
+        $1 "${ns...@]}" || failed=1
+    done < /etc/crypttab
+    return $failed
+}
+
 ###############################
 # Custom hooks in initscripts #
 ###############################
@@ -278,7 +312,7 @@ run_hook() {
     [[ $1 ]] || return 1
     local func
     for func in ${hook_funcs["$1"]}; do
-       "${func}"
+       q"${func}"
     done
 }
 
@@ -293,13 +327,14 @@ set_consolefont() {
     for i in /dev/tty[0-9]*; do
        /usr/bin/setfont ${CONSOLEMAP:+-m ${CONSOLEMAP}} \
            $CONSOLEFONT -C ${i} >/dev/null 2>&1
-    done
+   done
     if (($? != 0)); then
        stat_fail
     elif [[ $CONSOLEMAP ]]; then
        cat <<"EOF" >>/etc/profile.d/locale.sh
-if [ "$CONSOLE" = "" -a "$TERM" = "linux" -a -t 1 ]; then printf "\033(K"; fi
-
+if [ "$CONSOLE" = "" -a "$TERM" = "linux" -a -t 1 ]
+    then printf "\033(K"
+fi
 EOF
        stat_done
     fi
diff --git a/rc.shutdown b/rc.shutdown
index e823ed2..1081970 100755
--- a/rc.shutdown
+++ b/rc.shutdown
@@ -65,33 +65,17 @@ stat_busy "Unmounting Filesystems"
 stat_done
 
 # Kill non-root encrypted partition mappings
-if [[ -f /etc/crypttab ]]; then
+if [[ -f /etc/crypttab && $CS ]]; then
        stat_busy "Deactivating encrypted volumes:"
-       # Arch cryptsetup packages traditionally contained the binaries
-       #  /usr/sbin/cryptsetup
-       #  /sbin/cryptsetup.static
-       # By default, initscripts used the /sbin/cryptsetup.static.
-       # Newer packages will only have /sbin/cryptsetup and no static binary
-       # This ensures maximal compatibility with the old and new layout
-       for CS in /sbin/cryptsetup /usr/sbin/cryptsetup \
-           /sbin/cryptsetup.static ''; do
-           [[ -x $CS ]] && break
-       done
-       if [[ ! $CS ]]; then
-           stat_append " Failed, unable to find cryptsetup."
-           stat_fail
-       else
-           while read name src passwd opts; do
-               [[ ! $name || ${name:0:1} = '#']] && continue
-               [[ -b /dev/mapper/$name ]] || continue
-               stat_append "${1}.."
-               if "$CS" remove "$name" >/dev/null 2>&1; then
-                   stat_append "ok "
-               else
-                   stat_append "failed "
-               fi
-           done </etc/crypttab
-       fi
+       do_lock() {
+            stat_append "${1}.."
+            if $CS remove "$1" >/dev/null 2>&1; then
+                stat_append "ok "
+           else
+                stat_append "failed "
+           fi
+        }
+        read_crypttab do_lock
        stat_done
 fi
 
diff --git a/rc.sysinit b/rc.sysinit
index 404e11a..d54b9bb 100755
--- a/rc.sysinit
+++ b/rc.sysinit
@@ -127,104 +127,55 @@ if [[ -f /etc/mdadm.conf ]] && /bin/grep -q ^ARRAY 
/etc/mdadm.conf; then
        status "Activating RAID arrays" /sbin/mdadm --assemble --scan
 fi
 
-if [ "$USELVM" = "yes" -o "$USELVM" = "YES" ]; then
-       if [ -x /sbin/lvm -a -d /sys/block ]; then
-               # Kernel 2.6.x, LVM2 groups
-               /sbin/modprobe -q dm-mod 2>/dev/null
-               stat_busy "Activating LVM2 groups"
-               /sbin/lvm vgchange --ignorelockingfailure -a y >/dev/null
-               if [ $? -ne 0 ]; then
-                       stat_fail
-               else
-                       stat_done
-               fi
-       fi
-fi
+activate_vgs
 
 # Set up non-root encrypted partition mappings
-if [ -f /etc/crypttab -a -n "$(/bin/grep -v ^# /etc/crypttab | /bin/grep -v 
^$)" ]; then
-       /sbin/modprobe -q dm-mod 2>/dev/null
+if [[ -f /etc/crypttab && $CS ]]; then
+       /sbin/modprobe -q dm-crypt 2>/dev/null
        stat_busy "Unlocking encrypted volumes:"
-       csfailed=0
-       # Arch cryptsetup packages traditionally contained the binaries
-       #  /usr/sbin/cryptsetup
-       #  /sbin/cryptsetup.static
-       # By default, initscripts used the /sbin/cryptsetup.static.
-       # Newer packages will only have /sbin/cryptsetup and no static binary
-       # This ensures maximal compatibility with the old and new layout
-       if [ -x /sbin/cryptsetup ]; then
-               CS=/sbin/cryptsetup
-       elif [ -x /usr/sbin/cryptsetup ]; then
-               CS=/usr/sbin/cryptsetup
-       else
-               CS=/sbin/cryptsetup.static
-       fi
-       do_crypt() {
-               if [ $# -ge 3 ]; then
-                       cname="$1"
-                       csrc="$2"
-                       cpass="$3"
-                       shift 3
-                       copts="$*"
-                       stat_append "${cname}.."
-                       # For some fun reason, the parameter ordering varies for
-                       # LUKS and non-LUKS devices.  Joy.
-                       if [ "${cpass}" = "SWAP" ]; then
-                               # This is DANGEROUS! The only possible safety 
check
-                               # is to not proceed in case we find a LUKS 
device
-                               # This may cause dataloss if it is not used 
carefully
-                               if $CS isLuks $csrc 2>/dev/null; then
-                                       false
-                               else
-                                       $CS -d /dev/urandom $copts create 
$cname $csrc >/dev/null
-                                       if [ $? -eq 0 ]; then
-                                               stat_append "creating 
swapspace.."
-                                               /sbin/mkswap -f -L $cname 
/dev/mapper/$cname >/dev/null
-                                       fi
-                               fi
-                       elif [ "${cpass}" = "ASK" ]; then
-                               printf "\nOpening '${cname}' volume:\n"
-
-                               if $CS isLuks $csrc 2>/dev/null; then
-                                       $CS $copts luksOpen $csrc $cname < 
/dev/console
-                               else
-                                       $CS $copts create $cname $csrc < 
/dev/console
-                               fi
-                       elif [ "${cpass:0:1}" != "/" ]; then
-                               if $CS isLuks $csrc 2>/dev/null; then
-                                       echo "$cpass" | $CS $copts luksOpen 
$csrc $cname >/dev/null
-                               else
-                                       echo "$cpass" | $CS $copts create 
$cname $csrc >/dev/null
-                               fi
-                       else
-                               if $CS isLuks $csrc 2>/dev/null; then
-                                       $CS -d $cpass $copts luksOpen $csrc 
$cname >/dev/null
-                               else
-                                       $CS -d $cpass $copts create $cname 
$csrc >/dev/null
-                               fi
-                       fi
-                       if [ $? -ne 0 ]; then
-                               csfailed=1
-                               stat_append "failed "
-                       else
-                               stat_append "ok "
-                       fi
-               fi
-       }
-       while read line; do
-               eval do_crypt "$line"
-       done </etc/crypttab
-       if [ $csfailed -eq 0 ]; then
+        do_unlock() {
+            # $1 = requested name
+            # $2 = source device
+            # $3 = password
+            # $4 = options
+            local open=create a="$1" b="$2" failed=0
+            # Ordering of options is different if you are using LUKS vs. not.
+            # Use ugly swizzling to deal with it.
+            if $CS isLuks "$2"; then
+                open=luksOpen
+                a="$2"
+                b="$1"
+            fi  
+            case $3 in
+                SWAP) if [[ $_isluks ]]; then 
+                          # This is DANGEROUS! The only possible safety check
+                         # is to not proceed in case we find a LUKS device
+                         # This may cause dataloss if it is not used carefully
+                          false
+                      elif $CS -d /dev/urandom $4 $open "$a" "$b" >/dev/null; 
then
+                         stat_append "creating swapspace.."
+                         /sbin/mkswap -f -L $1 /dev/mapper/$1 >/dev/null
+                     fi;;
+                ASK) printf "\nOpening '$1' volume:\n"
+                     $CS $4 $open "$a" "$b" < /dev/console;;
+                /*)  $CS -d "$3" $4 $open "$a" "$b" >/dev/null;;
+               *) echo "$3" | $CS $4 $open "$a" "$b" >/dev/null;;
+            esac
+           if (($? != 0)); then
+               failed=1
+               stat_append "failed "
+           else
+               stat_append "ok "
+           fi
+            return $failed
+        }
+       if read_crypttab do_unlock; then
                stat_done
        else
                stat_fail
        fi
        # Maybe someone has LVM on an encrypted block device
-       if [ "$USELVM" = "yes" -o "$USELVM" = "YES" ]; then
-               if [ -x /sbin/lvm -a -d /sys/block ]; then
-                       /sbin/lvm vgchange --ignorelockingfailure -a y 
>/dev/null
-               fi
-       fi
+        activate_vgs
 fi
 
 status "Mounting Root Read-only" /bin/mount -n -o remount,ro /
-- 
1.7.1

Reply via email to