summaryrefslogtreecommitdiffstats
path: root/init_functions
diff options
context:
space:
mode:
Diffstat (limited to 'init_functions')
-rw-r--r--init_functions175
1 files changed, 117 insertions, 58 deletions
diff --git a/init_functions b/init_functions
index 05f4ab0..d5a584e 100644
--- a/init_functions
+++ b/init_functions
@@ -114,74 +114,133 @@ set_log_option() {
done
}
-parse_cmdline() {
- local _w _quoted _lhs _rhs _cmdline
- read -r _cmdline
- for _w in $_cmdline; do
- if [ -z "$_quoted" ]; then
- case $_w in
- # ignore everything after a # in the commandline
- \#*) break ;;
- # special cases
- rw|ro) rwopt=$_w ;;
- fstype) rootfstype=$_w ;;
- fsck.mode=*)
- case ${_w#*=} in
- force)
- forcefsck=y
- ;;
- skip)
- fastboot=y
- ;;
- *)
- err "unknown fsck.mode parameter: '${_w#*=}'"
- ;;
- esac
+startswith() {
+ local word=$1 prefix=$2
+
+ case $word in
+ $prefix*)
+ return 0
+ ;;
+ esac
+
+ return 1
+}
+
+endswith() {
+ local word=$1 suffix=$2
+
+ case $word in
+ *$suffix)
+ return 0
+ ;;
+ esac
+
+ return 1
+}
+
+parse_cmdline_item() {
+ local key=$1 value=$2
+
+ case $key in
+ rw|ro)
+ rwopt=$key
+ ;;
+ fstype)
+ # The kernel understands 'rootfstype', but mkinitcpio has (without
+ # documentation) supported 'fstype' instead. Ensure we support both
+ # for backwards compat, but make fstype legacy.
+ rootfstype=$value
+ ;;
+ fsck.mode)
+ case $value in
+ force)
+ forcefsck=y
;;
- rd.*)
- case ${_w#rd.} in
- debug)
- rd_debug=y
- ;;
- log)
- rd_logmask=$(( _rdlog_kmsg | _rdlog_cons ))
- ;;
- log=*)
- set_log_option "${_w#rd.log=}"
- ;;
- esac
+ skip)
+ fastboot=y
;;
- # abide by shell variable naming rules
- [[:alpha:]_]*=*)
- _rhs=${_w#*=}
- _lhs=${_w%%=*}
- _lhs=${_lhs//[-.]/_}
- if [ '"' = "${_rhs:0:1}" ]; then
- if [ '"' = "${_rhs:$((${#_rhs}-1))}" ]; then
- _rhs="${_rhs:1:$((${#_rhs}-2))}"
- else
- _rhs=${_rhs:1}
- _quoted=1
- continue
- fi
+ *)
+ err "unknown fsck.mode parameter: '$value'"
+ ;;
+ esac
+ ;;
+ rd.debug)
+ rd_debug=y
+ ;;
+ rd.log)
+ if [ -n "$value" ]; then
+ set_log_option "$value"
+ else
+ rd_logmask=$(( _rdlog_kmsg | _rdlog_cons ))
+ fi
+ ;;
+ [![:alpha:]_]*|[[:alpha:]_]*[![:alnum:]_]*)
+ # invalid shell variable, ignore it
+ ;;
+ *)
+ # valid shell variable
+ eval "$key"='${value:-y}'
+ ;;
+ esac
+}
+
+process_cmdline_param() {
+ local item_callback=$1 key=$2 value=$3
+
+ # maybe unquote the value
+ if startswith "$value" "[\"']" && endswith "$value" "${value:0:1}"; then
+ value=${value#?} value=${value%?}
+ fi
+
+ "$item_callback" "$key" "$value"
+}
+
+parse_cmdline() {
+ local item_callback=${1:-parse_cmdline_item}
+ local cmdline word quoted key value
+
+ set -f
+ read -r cmdline
+ set -- $cmdline
+ set +f
+
+ for word; do
+ if [ -n "$quoted" ]; then
+ value="$value $word"
+ else
+ case $word in
+ *=*)
+ key=${word%%=*}
+ value=${word#*=}
+
+ if startswith "$value" "[\"']"; then
+ quoted=${value:0:1}
fi
- eval $_lhs=\$_rhs
;;
- [[:alpha:]_]*)
- _lhs=${_w//[-.]/_}
- eval $_lhs=y
+ '#'*)
+ break
+ ;;
+ *)
+ key=$word
;;
esac
- else
- if [ '"' = "${_w:$((${#_w}-1))}" ]; then
- _rhs="$_rhs ${_w%\"}"
- unset _quoted
- eval $_lhs=\$_rhs
+ fi
+
+ if [ -n "$quoted" ]; then
+ if endswith "$value" "$quoted"; then
+ unset quoted
else
- _rhs="$_rhs $_w"
+ continue
fi
fi
+
+ process_cmdline_param "$item_callback" "$key" "$value"
+ unset key value
done
+
+ if [ -n "$key" ]; then
+ process_cmdline_param "$item_callback" "$key" "$value"
+ fi
}
fsck_device() {