lvm: start lvm2-lvmetad only if present + support lvm2-lvmpolld
[grml-autoconfig.git] / autoconfig.functions
1 #!/bin/zsh
2 # Filename:      autoconfig.functions
3 # Purpose:       basic system configuration and hardware setup for grml system
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 ################################################################################
8
9 # {{{ path, variables, signals, umask, zsh
10 export PATH="/bin:/sbin:/usr/bin:/usr/sbin"
11 DEBUG="/dev/null"
12 KERNEL="$(uname -r)"
13 ARCH="$(uname -m)"
14 umask 022
15
16 # initramfs layout since December 2012, backwards compatibility:
17 [ -d /lib/live/mount/medium ] && export LIVECD_PATH='/lib/live/mount/medium'
18 # initramfs layout since December 2018:
19 [ -d /run/live/medium ] && export LIVECD_PATH='/run/live/medium'
20
21 # Ignore these signals in non-interactive mode: INT, TERM, SEGV
22 [ -z "$PS1" ] && trap "" 2 3 11
23
24 if [ "$(cat /proc/1/comm 2>/dev/null)" = "systemd" ] ; then
25   SYSTEMD=true
26 else
27   SYSTEMD=false
28 fi
29
30 service_wrapper() {
31   if [ "$#" -lt 2 ] ; then
32     echo "Usage: service_wrapper <service> <action> [background]" >&2
33     return 1
34   fi
35
36   local service="$1"
37   local action="$2"
38   local background="$3"
39
40   if $SYSTEMD ; then
41     systemctl "$action" "$service"
42   else
43     if [ "${background:-}" = "background" ] ; then
44       /etc/init.d/"$service" "$action" &
45     else
46       /etc/init.d/"$service" "$action"
47     fi
48   fi
49 }
50
51 # zsh stuff
52 iszsh(){
53 if [ -n "$ZSH_VERSION" ] ; then
54   return 0
55 else
56   return 1
57 fi
58 }
59 # avoid 'no matches found: ...'
60 iszsh && setopt no_nomatch # || echo "Warning: not running under zsh!"
61 # }}}
62
63 # {{{ Read in boot parameters
64 if [ -z "$CMDLINE" ]; then
65   # if CMDLINE was set from the outside, we're debugging.
66   # otherwise, take CMDLINE from Kernel and config files.
67   CMDLINE="$(cat /proc/cmdline)"
68   [ -d ${LIVECD_PATH}/bootparams/ ] && CMDLINE="$CMDLINE $(cat ${LIVECD_PATH}/bootparams/* | tr '\n' ' ')"
69   modprobe 9p 2>/dev/null || true
70   if grep -q 9p /proc/filesystems ; then
71       TAG="grml-parameters"
72       if grep -q "$TAG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then
73           MOUNTDIR="$(mktemp -d)"
74           mount -t 9p -o trans=virtio,ro "$TAG" "$MOUNTDIR"
75           CMDLINE="$CMDLINE $(cat "$MOUNTDIR"/* 2>/dev/null | tr '\n' ' ')"
76           umount "$MOUNTDIR"
77           rmdir "$MOUNTDIR"
78       fi
79   fi
80 fi
81 # }}}
82
83 ### {{{ Utility Functions
84
85 # Get a bootoption's parameter: read boot command line and either
86 # echo last parameter's argument or return false.
87 getbootparam(){
88   local line
89   local ws
90   ws='   '
91   line=" $CMDLINE "
92   case "$line" in
93     *[${ws}]"$1="*)
94       result="${line##*[$ws]$1=}"
95       result="${result%%[$ws]*}"
96       echo "$result"
97       return 0 ;;
98     *) # no match?
99       return 1 ;;
100   esac
101 }
102
103 # Check boot commandline for specified option
104 checkbootparam(){
105   [ -n "$1" ] || ( echo "Error: missing argument to checkbootparam()" ; return 1 )
106   local line
107   local ws
108   ws='   '
109   line=" $CMDLINE "
110   case "$line" in
111     *[${ws}]"$1"=*|*[${ws}]"$1"[${ws}]*)
112       return 0 ;;
113     *)
114       return 1 ;;
115   esac
116 }
117
118 # Check if currently using a framebuffer
119 hasfb() {
120     [ -e /dev/fb0 ] && return 0 || return 1
121 }
122
123 # Check wheter a configuration variable (like $CONFIG_TOHD) is
124 # enabled or not
125 checkvalue(){
126   case "$1" in
127     [yY][eE][sS])     return 0 ;; # it's set to 'yes'
128     [tT][rR][uU][eE]) return 0 ;; # it's set to 'true'
129                    *) return 1 ;; # default
130   esac
131 }
132
133 # Are we using grml-small?
134 checkgrmlsmall(){
135   grep -q small /etc/grml_version 2>>$DEBUG && return 0 || return 1
136 }
137
138 # if no password is set return a random password
139 set_passwd() {
140   [ -n "$PASSWD" ] && return 0
141
142   if [ -x /usr/bin/apg ] ; then
143     PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
144   elif [ -x /usr/bin/gpw ] ; then
145     PASSWD="$(gpw 1)"
146   elif [ -x /usr/bin/pwgen ] ; then
147     PASSWD="$(pwgen -1 8)"
148   elif [ -x /usr/bin/hexdump ] ; then
149     PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
150   elif [ -n "$RANDOM" ] ; then
151     PASSWD="grml${RANDOM}"
152   else
153     PASSWD=''
154     eerror "Empty passphrase and neither apg, gpw, pwgen, hexdump nor \$RANDOM available. Skipping."
155     eend 1
156     return 1
157   fi
158 }
159
160 ### }}}
161
162 # {{{ filesystems (proc, pts, sys) and fixes
163 mount_proc(){
164   [ -f /proc/version ] || mount -t proc /proc /proc 2>/dev/null
165 }
166
167 mount_pts(){
168   grep -q "/dev/pts" /proc/mounts || mount -t devpts /dev/pts /dev/pts 2>/dev/null
169 }
170
171 mount_sys(){
172   [ -d /sys/devices ] || mount -t sysfs /sys /sys 2>/dev/null
173 }
174 # }}}
175
176 # {{{ Check if we are running in live mode or from HD
177 INSTALLED=""
178 [ -e /etc/grml_cd ] || INSTALLED="yes"
179 # }}}
180
181 # {{{ provide information about virtual environments
182 VIRTUAL=false # assume physical system by default
183 KVM=false
184 VIRTUALBOX=false
185 VMWARE=false
186
187 if vmware-detect &>/dev/null; then
188   VIRTUAL=true; VMWARE=true; VIRTUAL_ENV='VMware'
189 fi
190
191 if virt-what 2>/dev/null | grep -q 'kvm' || \
192   [ "$(imvirt 2>/dev/null)" = "KVM" ] ; then
193   VIRTUAL=true; KVM=true; VIRTUAL_ENV='KVM'
194 fi
195
196 if virt-what 2>/dev/null | grep -q 'virtualbox' || \
197   [ "$(imvirt 2>/dev/null)" = "VirtualBox" ] ; then
198   VIRTUAL=true; VIRTUALBOX=true; VIRTUAL_ENV='VirtualBox'
199 fi
200 # }}}
201
202 # {{{ source lsb-functions , color handling
203 if checkbootparam 'nocolor'; then
204   . /etc/grml/lsb-functions
205   einfo "Disabling colors in bootsequence as requested on commandline." ; eend 0
206 else
207   . /etc/grml/lsb-functions
208 fi
209 # }}}
210
211 # {{{ log
212 config_log(){
213 if checkbootparam 'log' || checkbootparam 'debug' ; then
214    export DEBUG="/tmp/grml.log.`date +%Y%m%d`"
215    touch $DEBUG
216    einfo "Bootparameter log found. Log files: ${DEBUG} and /var/log/boot"
217    eindent
218      einfo "Starting bootlogd." # known to be *very* unreliable :(
219      bootlogd -r -c >>$DEBUG 2>&1 ; eend $?
220    eoutdent
221 else
222    DEBUG="/dev/null"
223 fi
224 }
225 # }}}
226
227 ### {{{ language configuration / localization
228 config_language(){
229
230   einfo "Activating language settings:"
231   eindent
232
233   # people can specify $LANGUAGE and $CONSOLEFONT in a config file
234   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
235
236   # check for bootoption which overrides config from /etc/grml/autoconfig
237   BOOT_LANGUAGE="$(getbootparam 'lang' 2>>$DEBUG)"
238   [ -n "$BOOT_LANGUAGE" ] && LANGUAGE="$BOOT_LANGUAGE"
239
240   # set default to 'en' in live-cd mode iff $LANGUAGE is not set yet
241   if [ -z "$INSTALLED" ] ; then
242     [ -n "$LANGUAGE" ] || LANGUAGE='en'
243   fi
244
245   if [ -x /usr/sbin/grml-setlang ] ; then
246     # if bootoption lang is used update /etc/default/locale accordingly
247     if [ -n "$BOOT_LANGUAGE" ] ; then
248       /usr/sbin/grml-setlang "$LANGUAGE"
249       # otherwise default to lang=en
250     else
251       /usr/sbin/grml-setlang "en"
252     fi
253   fi
254
255   if ! $SYSTEMD ; then
256     # set console font
257     if [ -z "$CONSOLEFONT" ] ; then
258       if ! checkbootparam 'nodefaultfont' >>$DEBUG 2>&1 ; then
259         if [ -r /usr/share/consolefonts/Uni3-Terminus16.psf.gz ] ; then
260           CONSOLEFONT='Uni3-Terminus16'
261         else
262           ewarn "/usr/share/consolefonts/Uni3-Terminus16.psf.gz not available. Please upgrade package console-terminus." ; eend 1
263         fi
264         if ! hasfb ; then
265           CONSOLEFONT='Lat15-Terminus16'
266         fi
267       fi
268     fi
269   fi # not running systemd
270
271   # export it now, so error messages get translated, too
272   [ -r /etc/default/locale ] && . /etc/default/locale
273   export LANG LANGUAGE
274
275   if $SYSTEMD ; then
276     local KEYBOARD
277     KEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
278     [ -n "$KEYBOARD" ] || KEYBOARD="$LANGUAGE"
279     # "symbols/en" doesn't exist, so rewrite to "us"
280     [[ "$KEYBOARD" == 'en' ]] && KEYBOARD="us"
281
282     if [ -r /etc/default/keyboard ] ; then
283       sed -i "s/^XKBLAYOUT=.*/XKBLAYOUT=\"$KEYBOARD\"/" /etc/default/keyboard
284
285       case "$KEYBOARD" in
286         de|at)
287           sed -i "s/^XKBVARIANT=.*/XKBVARIANT=\"nodeadkeys\"/" /etc/default/keyboard
288           ;;
289       esac
290
291     fi
292     service_wrapper console-setup restart >>$DEBUG 2>&1 ; eend $?
293   else # not running systemd, keeing for backwards compatibility:
294     # configure keyboard layout, read in already set values first:
295     [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
296
297     # now allow keyboard override by boot commandline for later use:
298     KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
299     [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
300     # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
301     [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
302     [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
303
304     # modify /etc/sysconfig/keyboard only in live-cd mode:
305     if [ -z "$INSTALLED" ] ; then
306
307       local LANGUAGE="$BOOT_LANGUAGE"
308       . /etc/grml/language-functions
309       # allow setting xkeyboard explicitly different than console keyboard
310       KXKEYBOARD="$(getbootparam 'xkeyboard' 2>>$DEBUG)"
311       if [ -n "$KXKEYBOARD" ]; then
312         XKEYBOARD="$KXKEYBOARD"
313         KDEKEYBOARD="$KXKEYBOARD"
314       elif [ -n "$KKEYBOARD" ]; then
315         XKEYBOARD="$KKEYBOARD"
316         KDEKEYBOARD="$KKEYBOARD"
317       fi
318
319       # duplicate of previous code to make sure /etc/grml/language-functions
320       # does not overwrite our values....
321       # now allow keyboard override by boot commandline for later use:
322       KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
323       [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
324       # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
325       [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
326       [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
327
328       # write keyboard related variables to file for later use
329       [ -d /etc/sysconfig ] || mkdir /etc/sysconfig
330       if ! [ -e /etc/sysconfig/keyboard ] ; then
331         echo "KEYTABLE=\"$KEYTABLE\""          > /etc/sysconfig/keyboard
332         echo "XKEYBOARD=\"$XKEYBOARD\""       >> /etc/sysconfig/keyboard
333         echo "KDEKEYBOARD=\"$KDEKEYBOARD\""   >> /etc/sysconfig/keyboard
334         echo "KDEKEYBOARDS=\"$KDEKEYBOARDS\"" >> /etc/sysconfig/keyboard
335       fi
336     fi
337
338     [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
339   fi
340
341
342   if ! $SYSTEMD ; then
343     # we have to set up all consoles, therefore loop it over all ttys:
344     NUM_CONSOLES=$(fgconsole --next-available 2>/dev/null)
345     if [ -n "$NUM_CONSOLES" ] ; then
346       NUM_CONSOLES=$(expr ${NUM_CONSOLES} - 1)
347       [ ${NUM_CONSOLES} -eq 1 ] && NUM_CONSOLES=6
348     fi
349     CUR_CONSOLE=$(fgconsole 2>/dev/null)
350
351     if [ -x "$(which setfont)" ] ; then
352       use_setfont=true
353     elif [ -x "$(which consolechars)" ] ; then
354       use_consolechars=true
355     else
356       eerror "Neither setfont nor consolechars tool present, can not set font."
357       eend 1
358       return 1
359     fi
360
361     if [ -n "$CHARMAP" ] ; then
362       einfo "Setting font to ${CHARMAP}"
363       RC=0
364       for vc in $(seq 0 ${NUM_CONSOLES}) ; do
365         if $use_setfont ; then
366           setfont -C /dev/tty${vc} $CHARMAP ; RC=$?
367         elif $use_consolechars ; then
368           consolechars --tty=/dev/tty${vc} -m ${CHARMAP} ; RC=$?
369         fi
370       done
371       if [ -n "$CUR_CONSOLE" ] ; then
372         [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
373       fi
374       eend $RC
375     fi
376
377     if checkbootparam 'noconsolefont' ; then
378       ewarn "Skipping setting console font as requested on boot commandline." ; eend 0
379     else
380       if [ -n "$CONSOLEFONT" ] ; then
381         einfo "Setting font to ${CONSOLEFONT}"
382         RC=0
383         for vc in $(seq 0 ${NUM_CONSOLES}) ; do
384           if $use_setfont ; then
385             setfont -C /dev/tty${vc} ${CONSOLEFONT} ; RC=$?
386           elif $use_consolechars ; then
387             consolechars --tty=/dev/tty${vc} -f ${CONSOLEFONT} ; RC=$?
388           fi
389         done
390         if [ -n "$CUR_CONSOLE" ] ; then
391           [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
392         fi
393         eend $RC
394       fi
395     fi
396
397     # Set default keyboard before interactive setup
398     if [ -n "$KEYTABLE" ] ; then
399       einfo "Running loadkeys for ${WHITE}${KEYTABLE}${NORMAL} in background"
400       loadkeys -q $KEYTABLE &
401       eend $?
402     fi
403
404     # activate unicode console if running within utf8 environment
405     if [ -r /etc/default/locale ] ; then
406       if grep -q "LANG=.*UTF" /etc/default/locale ; then
407         einfo "Setting up unicode environment."
408         unicode_start ; eend $?
409       fi
410     fi
411   fi # not running systemd
412
413   eoutdent
414 }
415 # }}}
416
417 # {{{ Set hostname
418 config_hostname(){
419   if ! checkbootparam 'hostname' ; then
420     return 0
421   fi
422
423   HOSTNAME="$(getbootparam 'hostname' 2>>$DEBUG)"
424   if [ -z "$HOSTNAME" ] && [ -x /usr/bin/random-hostname ] ; then
425     einfo "Generating random hostname as no hostname was specified."
426     HOSTNAME="$(/usr/bin/random-hostname)"
427     eend $?
428   fi
429
430   einfo "Setting hostname to $HOSTNAME as requested."
431   grml-hostname $HOSTNAME >>$DEBUG
432   eend $?
433 }
434 # }}}
435
436 # fstabuser (needed when running from harddisk with username != grml {{{
437 config_userfstab(){
438   # force load of build-in and local config
439   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
440   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig.local
441
442   # 1st. try configured fstab user
443   if [ -n "$CONFIG_FSTAB_USER" ] ; then
444      fstabuser=$(getent passwd $CONFIG_FSTAB_USER | cut -d: -f1)
445   fi
446
447   # 2nd. use standard user id
448   [ -n "$fstabuser" ] || fstabuser=$(getent passwd 1000 | cut -d: -f1)
449
450   # 3rd. use standard user name
451   [ -n "$fstabuser" ] || fstabuser=$(getent passwd grml | cut -d: -f1)
452
453   # if not yet set fall back to 'root' user, avoid bad /etc/fstab
454   [ -n "$fstabuser" ] || fstabuser='root'
455 }
456 # }}}
457
458 # local_user (needed when running with username != grml {{{
459 config_userlocal() {
460
461   # force load of build-in and local config
462   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
463   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig.local
464
465   # 1st. try id of primary user
466   localuser=$(getent passwd 1000 | cut -d: -f1)
467
468   # 2nd. use name standard user
469   [ -n "$localuser" ] || localuser=$(getent passwd grml | cut -d: -f1)
470 }
471 # }}}
472
473 # {{{ Set clock (Local time is more often used than GMT, so it is default)
474 config_time(){
475  # don't touch the files if running from harddisk:
476  if [ -z "$INSTALLED" ]; then
477     # The default hardware clock timezone is stated as representing local time.
478     UTC="--localtime"
479
480     if [ -f /etc/default/rcS ] ; then
481       grep -q "^UTC=" /etc/default/rcS || echo "UTC=no" >> /etc/default/rcS
482       checkbootparam 'utc'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
483       checkbootparam 'gmt'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
484       checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=no|"  /etc/default/rcS
485       grep -q -i "^UTC=yes" /etc/default/rcS && UTC="-u"
486     # recent initscripts package versions don't ship /etc/default/rcS anymore, instead rely on /etc/adjtime
487     elif [ -f /etc/adjtime ] ; then
488       checkbootparam 'utc'       >>$DEBUG 2>&1 && sed -i "s/^LOCAL/UTC/" /etc/adjtime
489       checkbootparam 'gmt'       >>$DEBUG 2>&1 && sed -i "s/^LOCAL/UTC/" /etc/adjtime
490       checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s/^UTC$/LOCAL/" /etc/adjtime
491       grep -q "^UTC$" /etc/adjtime && UTC="-u"
492     fi
493
494     # hwclock uses the TZ variable
495     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
496     [ -z "$KTZ" ] && [ -r /etc/timezone ] && KTZ=$(cat /etc/timezone)
497     if [ ! -f "/usr/share/zoneinfo/$KTZ" ] ; then
498        ewarn "Warning: unknown timezone $KTZ" ; eend 1
499        KTZ="UTC"
500        ewarn "Falling back to timezone $KTZ" ; eend 0
501     fi
502
503     if ! [ -r /dev/rtc ] ; then
504       ewarn "Warning: realtime clock not available, trying to execute hwclock anyway." ; eend 0
505     fi
506
507     ERROR=$(TZ="$KTZ" hwclock $UTC -s 2>&1 | head -1) ; RC=$?
508     if [ -n "$ERROR" ] ; then
509        eindent
510        ERROR=$(TZ="$KTZ" hwclock $UTC -s --directisa 2>&1 | head -1)
511        if [ -n "$ERROR" ] ; then
512           eerror "Problem running hwclock: $ERROR" ; eend 1
513        fi
514        eoutdent
515     fi
516
517  fi
518 }
519 # }}}
520
521 # {{{ print kernel info
522 config_kernel(){
523   if $VIRTUAL && [ -n "$VIRTUAL_ENV" ] ; then
524     einfo "Running Linux Kernel $KERNEL inside $VIRTUAL_ENV" ; eend 0
525   else
526     einfo "Running Linux Kernel $KERNEL" ; eend 0
527   fi
528
529   if [ -r /proc/cpuinfo ] ; then
530     if egrep -q '^flags.*(vmx|svm)' /proc/cpuinfo ; then
531       eindent
532       einfo 'CPU(s) featuring virtualization technology detected' ; eend 0
533       eoutdent
534     fi
535   fi
536
537   if [ -d /proc/xen ] ; then
538     eindent
539     einfo 'Running kernel featuring support for Xen detected' ; eend 0
540     eoutdent
541   fi
542 }
543 # }}}
544
545 # {{{ secure boot
546 config_secureboot(){
547   # systemd does this for us, but if we are not running under systemd then mokutil
548   # doesn't work as needed as it relies on /sys/firmware/efi/efivars (while
549   # /sys/firmware/efi/vars would exist)
550   if ! $SYSTEMD ; then
551     if modprobe efivars &>/dev/null ; then
552       mount -t efivarfs efivarfs /sys/firmware/efi/efivars
553     fi
554   fi
555
556   if [ -x /usr/bin/mokutil ] ; then
557     local secstate=$(mokutil --sb-state 2>/dev/null) # "SecureBoot enabled"
558     if [ -n "$secstate" ] ; then
559       einfo "SecureBoot is enabled" ; eend 0
560     else
561       einfo "SecureBoot not detected" ; eend 0
562     fi
563   else
564     if modprobe efivars &>/dev/null ; then
565       if od -An -t u1 /sys/firmware/efi/vars/SecureBoot-*/data 2>/dev/null | grep -q 1 ; then
566         einfo "SecureBoot is enabled" ; eend 0
567       else
568         einfo "SecureBoot not detected" ; eend 0
569       fi
570     fi
571   fi
572 }
573 # }}}
574
575 # {{{ timezone
576 config_timezone(){
577  # don't touch the files if running from harddisk:
578  if [ -z "$INSTALLED" ]; then
579     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
580     if [ -n "$KTZ" ] ; then
581        if [ ! -f "/usr/share/zoneinfo/$KTZ" ]
582        then
583           ewarn "Warning: unknown timezone $KTZ"; eend 0
584        else
585           einfo "Setting timezone."
586           # update debconf
587           area=$(echo $KTZ | cut -d '/' -f1)
588           zone=$(echo $KTZ | cut -d '/' -f2)
589           echo "tzdata tzdata/Areas       select $area" | debconf-set-selections
590           echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections
591           # update files
592           echo $KTZ > /etc/timezone
593           rm -f /etc/localtime
594           cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $?
595        fi
596     fi
597  fi
598 }
599 # }}}
600
601 # activate serial console {{{
602 config_console(){
603 if checkbootparam 'console'; then
604   # this hack is no longer necessary with systemd
605   if $SYSTEMD ; then
606     return
607   fi
608
609   local line
610   local ws
611   ws='   '
612
613   einfo "Bootoption for serial console detected:"
614
615   line="$CMDLINE x "
616   this=""
617   line="${line#*[$ws]}"
618   local telinitq=""
619   while [ -n "$line" ]; do
620     case "$this" in
621       console=*)
622         local serial="$this"
623         local device="${this%%,*}"
624         local device="${device##*=}"
625         if echo $serial | grep -q ttyS ; then
626           local option="${serial##*,}"
627           # default (works for kvm & CO):
628           local speed="115200,57600,38400,19200,9600,4800,2400,1200";
629           # ... unless overriden by command line:
630           case "$option" in
631             115200*) speed=115200 ;;
632              57600*) speed=57600 ;;
633              38400*) speed=38400 ;;
634              19200*) speed=19200 ;;
635               9600*) speed=9600 ;;
636               4800*) speed=4800 ;;
637               2400*) speed=2400 ;;
638               1200*) speed=1200 ;;
639           esac
640           eindent
641             einfo "Activating console login on device ${device} with speed ${speed}."
642             local number="${device#ttyS}"
643             sed -i "/^T$number:/d;/^#grmlserial#/iT$number:23:respawn:/bin/bash -c \"/sbin/getty -L $device -l /usr/share/grml-scripts/run-welcome $speed vt100 || sleep 30\"" /etc/inittab
644             eend $?
645             telinitq="1"
646           eoutdent
647         fi
648         ;;
649     esac
650     this="${line%%[$ws]*}"
651     line="${line#*[$ws]}"
652   done
653
654   if [ -n "$telinitq" ]; then
655     /sbin/telinit q
656   fi
657   eend $?
658 fi
659 }
660 # }}}
661
662 # {{{ CD Checker
663 config_testcd(){
664 if checkbootparam 'testcd' ; then
665   einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
666   eindent
667
668   local ERROR=true
669   local FOUND_FILE=false
670   local logfile='/tmp/md5sum.log'
671
672   rm -f "$logfile"
673
674   for md5 in $(find "${LIVECD_PATH}" -name md5sums) ; do
675     einfo "Checking files against $md5, this may take a while..."
676
677     FOUND_FILE=true
678     OLD_PWD=$(pwd)
679     cd $(dirname "$md5")
680     md5sum -c $(basename "$md5") |& tee -a "${logfile}"
681     if [ $pipestatus[1] -eq 0 ] ; then
682       ERROR=false
683     fi
684     cd "${OLD_PWD}"
685   done
686
687   if ! $FOUND_FILE ; then
688     eerror 'Error: Could not find md5sum file' ; eend 1
689     return
690   fi
691
692   if ! $ERROR ; then
693     einfo "Everything looks OK" ; eend 0
694   else
695     eerror 'Checksum failed for theses files:' ; eend 1
696     egrep -v '(^md5sum:|OK$)' "${logfile}"
697     eerror 'Data on the medium is possibly incomplete/damaged or RAM of your system is broken.' ; eend 1
698     einfon "Hit return to continue, or press the power button to shut down system."
699     read a
700   fi
701
702   eoutdent
703 fi
704 }
705 # }}}
706
707 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
708 config_blacklist(){
709 if checkbootparam 'blacklist' ; then
710  if [ -z "$INSTALLED" ]; then
711   einfo "Bootoption blacklist found."
712   BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
713   BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
714   if [ -n "$BLACK" ] ; then
715     for module in $(echo ${BLACK//,/ }) ; do
716         einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
717         echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
718         echo "blacklist $module"     >> "$BLACKLIST_FILE"
719         echo "alias     $module off" >> "$BLACKLIST_FILE"
720         echo "# end   entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
721     done
722   else
723    eerror "No given module for blacklist found. Blacklisting will not work therefore."
724   fi
725  else
726   ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
727   eindent
728    einfo "Please blacklist the module(s) manually using the 'blacklist' script."
729   eoutdent
730  fi
731 fi
732 }
733 # }}}
734
735 # {{{ ACPI
736 config_acpi(){
737   if $SYSTEMD ; then
738     echo "systemd detected, no acpi(d) stuff needed." >>"$DEBUG"
739     return
740   fi
741
742   if checkbootparam 'noacpi'; then
743     ewarn "ACPI: Not loading modules as requested by boot option \"noacpi\"." ; eend 0
744   elif checkbootparam 'nogrmlacpi' ; then
745     ewarn "ACPI: Not loading modules as requested by boot option \"nogrmlacpi\"." ; eend 0
746   elif [ ! -d /proc/acpi ] ; then
747     ewarn "ACPI: Kernel support not present." ; eend 0
748   else
749     einfo "ACPI: Loading modules (disable with boot option noacpi / nogrmlacpi): "
750     eindent
751     found=""
752     for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
753       basename="${a##*/}"
754       basename="${basename%%.*}"
755       case "$basename" in *_acpi)
756         egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
757     esac
758     modprobe $basename >>$DEBUG 2>&1 && found="yes"
759     local BASE="$BASE $basename"
760   done
761   if [ -n "$found" ] ; then
762     einfo "$BASE"  ; eend 0
763   else
764     ewarn "(none)" ; eend 1
765   fi
766   if ! pgrep acpid >/dev/null ; then
767     einfo "Starting acpi daemon."
768     service_wrapper acpid.socket start >>$DEBUG 2>&1 ; eend $?
769     service_wrapper acpid start >>$DEBUG 2>&1 ; eend $?
770   else
771     ewarn "acpi daemon already running."
772     eend 0
773   fi
774   eoutdent
775 fi
776 }
777 # }}}
778
779 # {{{ Start brltty
780 config_brltty() {
781   if checkbootparam 'brltty' ; then
782     einfo "Starting brltty service as requested on boot commandline."
783     service_wrapper brltty start ; eend $?
784   fi
785 }
786 # }}}
787
788 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
789 config_fstab(){
790
791 NOSWAP="yes" # we do not use swap by default!
792 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
793    NOSWAP=''
794    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
795 fi
796
797 # Scan for swap, config, homedir - but only in live-mode
798 if [ -z "$INSTALLED" ] ; then
799    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
800    GRML_IMG=""
801    GRML_SWP=""
802    HOMEDIR="$(getbootparam 'home')"
803    if [ -n "$partitions" ]; then
804       while read p m f relax; do
805         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
806         partoptions="users,exec"
807         fnew=""
808         # it's a swap partition?
809         case "$f" in swap)
810           eindent
811           if [ -n "$NOSWAP" ]; then
812              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
813              eend 0
814           else
815              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
816                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
817                      if [ -n "$ANYSWAP" ] ; then
818                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
819                         swapon $p 2>>$DEBUG ; eend $?
820                      else
821                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
822                      fi
823                      ;;
824                    *)
825                      if [[ "$p" == LABEL* ]] ; then
826                         p=$(blkid -t $p | awk -F: '{print $1}')
827                      fi
828                      if grep -q $p /proc/swaps ; then
829                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
830                      else
831                         if [ -b "$p" ] ; then
832                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
833                         swapon $p 2>>$DEBUG ; eend $?
834                         else
835                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
836                         fi
837                      fi
838                      ;;
839              esac # dd-check
840           fi # -n "$NOSWAP
841           eoutdent
842           continue
843           ;;
844         esac # it's a swap partition?
845
846         # mount read-only
847         MOUNTOPTS="ro"
848         case "$f" in
849           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
850           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
851           *) continue ;;
852           # *) NONEFOUND='1'; continue ;;
853         esac
854
855         # use a swapfile
856         if [ -z "$NOSWAP" ] ; then
857            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
858            # Activate swapfile, if exists
859            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
860         fi
861         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
862            mount -o remount,rw $m && MOUNTED=1
863            if swapon "$SWAPFILE" 2>>$DEBUG ; then
864               eindent
865                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
866               eoutdent
867               fnew="$SWAPFILE swap swap defaults 0 0"
868               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
869               GRML_SWP="$GRML_SWP $SWAPFILE"
870               eend 0
871            fi
872            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
873         fi
874
875         # use a image as home
876         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
877         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
878            if [ -n "$HOMEDIR" ]; then
879               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
880                  continue
881               fi
882            fi
883            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
884               GRML_IMG="$IMAGE"
885               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
886            fi
887         fi
888         eend 0
889
890         # Umount, if not in use
891         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
892
893       done <<EOT
894       $(cat /etc/fstab)
895 EOT
896    fi # -n $partitions
897 fi # -z $INSTALLED
898 }
899 # }}}
900
901 # {{{ CPU-detection
902 config_cpu(){
903 if checkbootparam 'nocpu'; then
904   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
905   return 0
906 fi
907
908 if [[ $(grep -c processor /proc/cpuinfo) -gt 1 ]] ; then
909    einfo "Found CPU:"
910    CPU=$(awk -F: '/^processor/{printf " Processor"$2" is"};/^model name/{printf $2};/^vendor_id/{printf vendor};/^cpu MHz/{printf " %dMHz",int($2)};/^cache size/{printf ","$2" Cache"};/^$/{print ""}' /proc/cpuinfo 2>>$DEBUG)
911    echo $CPU | sed 's/ \{1,\}/ /g'
912    eend 0
913 else
914    einfo "Found CPU: `awk -F: '/^processor/{printf " Processor"$2" is"};/^model name/{printf $2};/^vendor_id/{printf vendor};/^cpu MHz/{printf " %dMHz",int($2)};/^cache size/{printf ","$2" Cache"};/^$/{print ""}' /proc/cpuinfo 2>>$DEBUG` " ; eend 0
915 fi
916 }
917 # }}}
918
919 # {{{ autostart of ssh
920 config_ssh(){
921 if checkbootparam 'ssh' ; then
922    local PASSWD
923    PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
924
925    config_userlocal
926    einfo "Bootoption ssh found, trying to set password for root and user $localuser"
927    [ -z "$localuser" ] && eend 1
928
929    eindent
930    if [ -z "$PASSWD" ] ; then
931      set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0
932    fi
933    eoutdent
934
935    if [ -n "$PASSWD" ] ; then
936       chpass_options=""
937       if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
938         chpass_options="-m"
939       fi
940
941       echo "$localuser:$PASSWD" | chpasswd $chpass_options
942       echo "root:$PASSWD" | chpasswd $chpass_options
943
944       eindent
945       ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
946       eoutdent
947    fi
948
949    einfo "Starting secure shell server in background for root and user $localuser"
950    service_wrapper haveged start >>$DEBUG 2>>$DEBUG
951    service_wrapper rmnologin start >>$DEBUG 2>>$DEBUG
952    service_wrapper ssh start background >>$DEBUG 2>>$DEBUG
953    eend $?
954
955 fi
956 }
957
958 # }}}
959
960 # {{{ display hostkeys of SSH server
961 config_display_ssh_fingerprints() {
962   if ! ls /etc/ssh/ssh_host_\*_key >/dev/null 2>&1 ; then
963     return 0 # no SSH host keys present
964   fi
965
966   einfo "SSH key fingerprints:"
967   for file in /etc/ssh/ssh_host_*_key ; do
968     einfon
969     ssh-keygen -l -f $file
970   done | column -t
971   eend $?
972 }
973 # }}}
974
975 # {{{ autostart of x11vnc
976 config_vnc(){
977 if checkbootparam 'vnc' ; then
978    config_userlocal
979    VNC_PASSWD=''
980    VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)"
981    einfo "Bootoption vnc found, trying to set password for user $localuser."
982    eindent
983    if [ -z "$VNC_PASSWD" ] ; then
984       if [ -x /usr/bin/apg ] ; then
985          VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
986       elif [ -x /usr/bin/gpw ] ; then
987          VNC_PASSWD="$(gpw 1)"
988       elif [ -x /usr/bin/pwgen ] ; then
989          VNC_PASSWD="$(pwgen -1 8)"
990       elif [ -x /usr/bin/hexdump ] ; then
991          VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
992       elif [ -n "$RANDOM" ] ; then
993          VNC_PASSWD="${localuser}${RANDOM}"
994       else
995          VNC_PASSWD=''
996          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
997          eend 1
998       fi
999
1000       if [ -n "$VNC_PASSWD" ] ; then
1001          ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0
1002       fi
1003    fi
1004    eoutdent
1005
1006    # finally check if we have a password we can use:
1007    if [ -n "$VNC_PASSWD" ] ; then
1008
1009       VNCDIR="/home/${localuser}/.vnc"
1010       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1011
1012       if [ ! -x /usr/bin/x11vnc ] ; then
1013          eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package."
1014          eend 1
1015       else
1016          /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $?
1017          /bin/chown -R "$localuser": "$VNCDIR"
1018       fi
1019    fi
1020    if checkbootparam 'vnc_connect' ; then
1021       VNC_CONNECT=''
1022       VNC_CONNECT="$(getbootparam 'vnc_connect' 2>>$DEBUG)"
1023       einfo "Bootoption vnc_connect found, will start vnc with connect to $VNC_CONNECT."
1024       #store the options in a file
1025       VNCDIR="/home/${localuser}/.vnc"
1026       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1027       echo " --connect $VNC_CONNECT " >> $VNCDIR/options
1028    fi
1029 fi
1030 }
1031 # }}}
1032
1033 # {{{ set password for root and default user
1034 config_passwd(){
1035 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1036   local PASSWD
1037   PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1038
1039   config_userlocal
1040   einfo "Bootoption passwd found, trying to set password for root and user $localuser"
1041   [ -z "$localuser" ] && eend 1
1042
1043   eindent
1044   if [ -z "$PASSWD" ] ; then
1045     set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0
1046   fi
1047   eoutdent
1048
1049   if [ -n "$PASSWD" ] ; then
1050     chpass_options=""
1051     if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1052       chpass_options="-m"
1053     fi
1054
1055     echo "$localuser:$PASSWD" | chpasswd $chpass_options
1056     echo "root:$PASSWD" | chpasswd $chpass_options
1057
1058     eindent
1059     ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
1060     eoutdent
1061   fi
1062
1063 fi
1064
1065 if checkbootparam 'encpasswd' >>$DEBUG 2>&1; then
1066   local PASSWD
1067   PASSWD="$(getbootparam 'encpasswd' 2>>$DEBUG)"
1068
1069   if [ -z "$PASSWD" ] ; then
1070     eerror "No hashed password found, can not set password."
1071     eend 1
1072     return
1073   fi
1074
1075   config_userlocal
1076   einfo "Bootoption encpasswd found, trying to set hashed password for root and user $localuser"
1077   [ -z "$localuser" ] && eend 1
1078
1079   if [ -n "$PASSWD" ] ; then
1080     chpass_options="-e"
1081
1082     echo "$localuser:$PASSWD" | chpasswd $chpass_options
1083     echo "root:$PASSWD" | chpasswd $chpass_options
1084
1085     eindent
1086     ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
1087     eoutdent
1088   fi
1089
1090 fi
1091 }
1092 # }}}
1093
1094 # {{{ Sound
1095 config_mixer () {
1096   if ! [ -x /usr/bin/amixer ] ; then
1097     logger -t grml-autoconfig "amixer binary not available"
1098     return
1099   fi
1100
1101   if ! [ -r /proc/asound/cards ] ; then
1102     ewarn "No soundcard present, skipping mixer settings therefore."
1103     eend 0
1104     return
1105   fi
1106
1107   for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do
1108     einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\""
1109     eindent
1110
1111     if checkbootparam 'vol' ; then
1112       VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1113       if [ -z "$VOL" ] ; then
1114         eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)."
1115         VOL='75'
1116         eend 1
1117       fi
1118     else
1119       VOL='75'
1120     fi
1121
1122     if checkbootparam 'nosound' ; then
1123       einfo "Muting sound devices on request."
1124       ERROR=$(amixer -q set Master mute)
1125       RC=$?
1126       if [ -n "$ERROR" ] ; then
1127         eindent
1128         eerror "Problem muting sound devices: $ERROR"
1129         eoutdent
1130       fi
1131       eend $RC
1132     elif [ -z "$INSTALLED" ] ; then
1133       einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1134
1135       if checkbootparam 'micvol' ; then
1136         MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1137         einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1138       else
1139         MICVOL=0
1140       fi
1141
1142       CONTROLS=$(amixer -c $card scontrols | awk -F"Simple mixer control " '{print $2}')
1143       IFSOLD=${IFS:-}
1144       IFS=$'\n'
1145       for CONTROL in ${=CONTROLS} ; do
1146         # such devices can not be controlled with amixer ... unmute
1147         [[ "$CONTROL" == *Console* ]] && continue
1148
1149         if ! echo "${CONTROL}" | grep -q -i "mic" ; then
1150           if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*pswitch' ; then
1151             amixer -c $card -q set "${CONTROL}" unmute
1152           fi
1153           if amixer -c $card sget "${CONTROL}" | grep -q -P 'Capabilities:.*(pvolume| volume)' ; then
1154             amixer -c $card -q set "${CONTROL}" "${VOL}"%
1155           fi
1156         fi
1157
1158         if [ ${MICVOL} -ne 0 ] ; then
1159           if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cswitch' ; then
1160             amixer -c $card -q set "${CONTROL}" unmute
1161           fi
1162           if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cvolume' ; then
1163             amixer -c $card -q set "${CONTROL}" $MICVOL%
1164           fi
1165           eend $?
1166         fi
1167       done
1168       IFS=$IFSOLD
1169     fi # checkbootparam 'nosound'
1170     eoutdent
1171   done
1172 }
1173 # }}}
1174
1175 # {{{ syslog service
1176 config_syslog(){
1177  if checkbootparam 'nosyslog'; then
1178     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1179  else
1180     einfo "Starting rsyslog in background."
1181     service_wrapper rsyslog start >>$DEBUG
1182     eend 0
1183  fi
1184 }
1185 # }}}
1186
1187 # {{{ gpm
1188 config_gpm(){
1189   if checkbootparam 'nogpm'; then
1190     ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1191   else
1192     if ! [ -r /dev/input/mice ] ; then
1193       eerror "No mouse found - not starting GPM." ; eend 1
1194     else
1195       einfo "Starting gpm in background."
1196       service_wrapper gpm start background >>$DEBUG
1197       eend 0
1198     fi
1199   fi
1200 }
1201 # }}}
1202
1203 # {{{ services
1204 config_services(){
1205  if checkbootparam 'services' ; then
1206     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1207     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1208     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1209     for service in $(echo -e $SERVICELIST) ; do
1210       # support running (custom) init scripts in non-blocking mode
1211       # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1212       if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1213         einfo "Starting service ${service}."
1214         service_wrapper "${service}" start >>$DEBUG
1215       else
1216         einfo "Starting service ${service} in background."
1217         service_wrapper "${service}" start background >>$DEBUG
1218       fi
1219     done
1220     eend $?
1221  fi
1222 }
1223 # }}}
1224
1225 # {{{ remote files
1226 get_remote_file() {
1227   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1228   SOURCE=$(eval echo "$1")
1229   TARGET="$2"
1230   getconfig() {
1231   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1232        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1233   }
1234   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1235
1236   if checkbootparam 'getfile.retries' ; then
1237     local counter="$(getbootparam 'getfile.retries' 2>>$DEBUG)"
1238   else
1239     local counter=10
1240   fi
1241
1242   while ! getconfig && [[ "$counter" != 0 ]] ; do
1243     echo -n "Sleeping for 1 second and trying to get config again... "
1244     counter=$(( counter-1 ))
1245     echo "$counter tries left" ; sleep 1
1246   done
1247   if [ -s "$TARGET" ] ; then
1248     einfo "Downloading was successfull." ; eend 0
1249     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1250     md5sum ${TARGET} ; eend 0
1251     return 0;
1252   else
1253     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1254     return 1;
1255  fi
1256 }
1257 # }}}
1258
1259 # {{{ config files
1260 config_netconfig(){
1261  if checkbootparam 'netconfig' ; then
1262   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1263   CONFIGFILE='/tmp/netconfig.grml'
1264
1265   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1266     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1267   fi
1268
1269  fi
1270 }
1271 # }}}
1272
1273 # {{{ remote scripts
1274 config_netscript() {
1275  if checkbootparam 'netscript' ; then
1276   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1277   SCRIPTFILE='/tmp/netscript.grml'
1278
1279   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1280     chmod +x ${SCRIPTFILE}
1281     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1282   fi
1283
1284  fi
1285 }
1286 # }}}
1287
1288 # {{{ start X window system via grml-x
1289 config_x_startup(){
1290
1291
1292 # make sure we start X only if startx is used *before* a nostartx option
1293 # so it's possible to disable automatic X startup using nostart
1294 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1295  if [ -x "$(which X)" ] ; then
1296   if [ -z "$INSTALLED" ] ; then
1297    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1298    if [ -z "$WINDOWMANAGER" ] ; then
1299      einfo "No window manager specified. Using default one." && eend 0
1300    else
1301      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1302    fi
1303    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1304    config_userlocal
1305    if $SYSTEMD ; then
1306      if [ -n "$WINDOWMANAGER" ] ; then
1307        mkdir -p /var/run/grml-x/
1308        echo "$WINDOWMANAGER" > /var/run/grml-x/window-manager
1309      fi
1310      chvt 7
1311      return
1312    fi
1313    cat>|/etc/init.d/startx<<EOF
1314 #!/bin/sh
1315 su "${localuser}" -c "/usr/bin/grml-x ${WINDOWMANAGER}"
1316 EOF
1317    chmod 755 /etc/init.d/startx
1318
1319    # adjust inittab for startx
1320    if grep -q '^6:' /etc/inittab ; then
1321       sed -i 's|^6:.*|6:2345:respawn:/bin/zsh --login -c "/etc/init.d/startx ; /usr/share/grml-scripts/run-welcome" >/dev/tty6 2>\&1 </dev/tty6|' /etc/inittab
1322    else # just append tty6 to inittab if no definition is present:
1323       echo '6:2345:respawn:/bin/zsh --login -c "/etc/init.d/startx ; /usr/share/grml-scripts/run-welcome" >/dev/tty6 2>&1 < /dev/tty6' >> /etc/inittab
1324    fi
1325
1326    /sbin/telinit q ; eend $?
1327
1328    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1329       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1330    else
1331       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1332    fi
1333
1334   else
1335     eerror "We are not running in live mode - startx will not work, skipping it."
1336     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1337   fi
1338  else
1339    eerror "/usr/bin/X is not present on this grml flavour."
1340    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1341  fi
1342 fi
1343 }
1344 # }}}
1345
1346 # {{{ configuration framework
1347 config_extract(){
1348 if checkbootparam 'extract' ; then
1349  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1350  EXTRACTOPTIONS="-- -x $EXTRACT"
1351 fi
1352 }
1353
1354 config_finddcsdir() {
1355 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1356 #    on the command line, nothing is changed and the dcs files are
1357 #    searched within the .iso, $dcs-dir is set to the root directory
1358 #    within the .iso
1359 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1360 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1361 #    set, $dcs-dir is set to the root directory within the .iso.
1362 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1363 #    foo, even if a GRMLCFG partition is present.
1364 DCSDIR=""
1365 DCSMP="/mnt/grml"
1366 # autoconfig, see issue673
1367 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1368 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1369 if checkbootparam 'noautoconfig' ; then
1370   DCSDIR="${LIVECD_PATH}" # set default so it works for "scripts" boot option as expected
1371   ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1372 else
1373   if [ -z "$INSTALLED" ] ; then
1374     if checkbootparam 'myconfig' ; then
1375       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1376       if [ -z "$DCSDEVICE" ]; then
1377         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1378       fi # [ -z "$DCSDEVICE" ]
1379     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1380       einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1381       eindent
1382       DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1383
1384       modprobe 9p 2>/dev/null || true
1385       if [ -z "$DCSDEVICE" ] && grep -q 9p /proc/filesystems ; then
1386           if grep -q "$GRMLCFG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then
1387             einfo "Found 9p-virtio fs with mount_tag $GRMLCFG"
1388             DCSDEVICE="$GRMLCFG"
1389             MOUNTOPTIONS="ro,trans=virtio"
1390             DCSFS="9p"
1391           fi
1392       fi
1393
1394       if [ -n "$DCSDEVICE" ]; then
1395         DCSMP="/mnt/grmlcfg"
1396       fi
1397       eoutdent
1398     fi
1399
1400     # if not specified/present then assume default:
1401     if [ -z "$DCSDEVICE" ]; then
1402       DCSDIR="${LIVECD_PATH}"
1403     else
1404       eindent
1405       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1406       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1407       if [ -n "$DCSDIR" ]; then
1408         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1409       else
1410         [ -d $DCSMP ] || mkdir $DCSMP
1411         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1412         mount -o ${MOUNTOPTIONS:-ro} -t ${DCSFS:-auto} $DCSDEVICE  $DCSMP ; RC="$?"
1413         if [[ $RC == 0 ]]; then
1414           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1415         else
1416           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1417         fi
1418         DCSDIR="$DCSMP"
1419       fi
1420       eoutdent
1421     fi
1422   fi
1423 fi
1424
1425 if [ -n "$DCSDIR" -a "$DCSDIR" != "${LIVECD_PATH}" ] ; then
1426   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1427 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1428   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1429 fi
1430 }
1431
1432
1433 config_partconf() {
1434 if checkbootparam 'partconf' ; then
1435  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1436  if [ -n "$MOUNTDEVICE" ]; then
1437    [ -d /mnt/grml ] || mkdir /mnt/grml
1438    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1439     if [[ $RC == 0 ]]; then
1440       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1441       einfo "Copying files from $MOUNTDEVICE over grml system."
1442       for file in `cat /etc/grml/partconf` ; do
1443         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1444         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1445       done && eend 0
1446     else
1447       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1448     fi # mount $MOUNTDEVICE
1449    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1450  else
1451    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1452  fi # [ -n "$MOUNTDEVICE" ]
1453 fi
1454 }
1455 # }}}
1456
1457 # {{{ /cdrom/.*-options
1458 config_debs(){
1459 if checkbootparam 'debs' ; then
1460    iszsh && setopt localoptions shwordsplit
1461    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1462    if [ -z "$DEBS" ] ; then
1463       DEBS="*.deb"
1464    fi
1465    if ! echo $DEBS | grep -q '/'; then
1466      # backwards compatibility: if no path is given get debs from debs/
1467      DEBS="debs/$DEBS"
1468    fi
1469    einfo "Trying to install Debian package(s) ${DEBS}"
1470    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1471    dpkg -i $DEBS ; eend $?
1472 fi
1473 }
1474
1475 config_scripts(){
1476 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1477    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1478    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1479      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1480    fi
1481    if ! echo $SCRIPTS | grep -q '/'; then
1482      # backwards compatibility: if no path is given get scripts from scripts/
1483      SCRIPTS="scripts/$SCRIPTS"
1484    fi
1485    if [ -n "$SCRIPTS" ]; then
1486      SCRIPTS="${DCSDIR}/$SCRIPTS"
1487      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1488        einfo "Trying to execute ${SCRIPTS}"
1489        sh -c $SCRIPTS
1490        eend $?
1491      elif [ -d "$SCRIPTS" ]; then
1492        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1493        run-parts --regex '.*' $SCRIPTS
1494        eend $?
1495      else
1496        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1497        sh -c $SCRIPTS
1498        eend $?
1499      fi
1500    fi
1501 fi
1502 }
1503
1504 config_config(){
1505 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1506   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1507   if [ -z "$CONFIG" ]; then
1508     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1509   fi
1510   if [ -n "$CONFIG" ]; then
1511     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1512       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1513
1514       cp -a ${DCSDIR}/${CONFIG}/* /
1515     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1516       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1517
1518       cd /
1519       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1520     else
1521       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1522     fi
1523   fi
1524 fi
1525 }
1526 # }}}
1527
1528 # {{{ confing_umount_dcsdir
1529 config_umount_dcsdir(){
1530    # umount $DCSMP if it was mounted by finddcsdir
1531    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1532 }
1533 # }}}
1534
1535 # {{{ mypath
1536 config_mypath(){
1537 if checkbootparam 'mypath' ; then
1538    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1539    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1540    touch /etc/grml/my_path
1541    chmod 644 /etc/grml/my_path
1542    # make sure the directories exist:
1543    eindent
1544    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1545        if ! [ -d "$i" ] ; then
1546           einfo "Creating directory $i"
1547           mkdir -p "$i" ; eend $?
1548        fi
1549    done
1550    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1551    eoutdent
1552 fi
1553 }
1554 # }}}
1555
1556 # {{{ SW-RAID
1557 config_swraid(){
1558   [ -n "$INSTALLED" ] && return 0
1559
1560   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1561      checkbootparam 'raid=noautodetect' ; then
1562      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1563   else
1564     [ -e /proc/mdstat ] || modprobe md_mod
1565     if ! [ -x /sbin/mdadm ] ; then
1566        eerror "mdadm not available, can not execute it." ; eend 1
1567     else
1568
1569        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1570        # find out whether we have a valid configuration file already
1571        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1572           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1573           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1574           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1575         else
1576           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1577        fi
1578
1579        if ! checkbootparam 'swraid' ; then
1580           eindent
1581           if $SYSTEMD ; then
1582             einfo "Just run 'mdadm --assemble --scan' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1583           else
1584             einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1585           fi
1586           eoutdent
1587        else
1588           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1589           eindent
1590            IFSOLD=${IFS:-}
1591            IFS=$'\n'
1592            for line in $(mdadm --assemble --scan 2>&1) ; do
1593                case $line in
1594                  *'No arrays found'*)
1595                    ewarn "$line" ; eend 0
1596                    ;;
1597                  *)
1598                    einfo "$line" ; eend 0
1599                    ;;
1600                esac
1601            done
1602            IFS=$IFSOLD
1603          eoutdent
1604
1605          if [ -r /proc/mdstat ] ; then
1606             eindent
1607             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1608             if [ -z "$MDSTAT" ] ; then
1609                ewarn "No active arrays found" ; eend 0
1610             else
1611                IFSOLD=${IFS:-}
1612                IFS=$'\n'
1613                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1614                    einfo "active arrays: $line" ; eend 0
1615                done
1616                IFS=$IFSOLD
1617             fi
1618             eoutdent
1619          fi # /proc/mdstat
1620        fi # bootoption swraid
1621
1622      fi # is /sbin/mdadm executable?
1623   fi # check for bootoptions
1624 }
1625 # }}}
1626
1627 # {{{ dmraid
1628 config_dmraid(){
1629   [ -n "$INSTALLED" ] && return 0
1630
1631   if checkbootparam 'nodmraid' ; then
1632     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1633     return 0
1634   fi
1635
1636   if ! [ -x /sbin/dmraid ] ; then
1637     eerror "dmraid not available, can not execute it." ; eend 1
1638     return
1639   fi
1640
1641   dmraid_wrapper() {
1642     # usage: dmraid_wrapper <dmraid_option>
1643     [ -n "$1" ] || return 1
1644
1645     IFSOLD=${IFS:-}
1646     IFS=$'\n'
1647     eindent
1648
1649     for line in $(dmraid $1 ; echo errcode:$?); do
1650       case $line in
1651         *'no block devices found'*)
1652           einfo "No block devices found" ; eend 0
1653           break
1654           ;;
1655         *'no raid disks'*)
1656           einfo "No active dmraid devices found" ; eend 0
1657           break
1658           ;;
1659         errcode:0)
1660           eend 0;
1661           ;;
1662         errcode:1)
1663           eend 1
1664           ;;
1665         *)
1666           einfo "$line"
1667           ;;
1668       esac
1669     done
1670
1671     eoutdent
1672     IFS=$IFSOLD
1673   }
1674
1675   if checkbootparam 'dmraid' ; then
1676     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1677     if [ "$ACTION" = "off" ] ; then
1678       # Deactivates all active software RAID sets:
1679       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1680       dmraid_wrapper -an
1681     else
1682       # Activate all software RAID sets discovered:
1683       einfo "Activating present dmraid sets (as requested via dmraid):"
1684       dmraid_wrapper -ay
1685     fi
1686
1687     return
1688   fi
1689
1690   # by default (no special bootoptions) discover all software RAID devices:
1691   einfo "Searching for any present dmraid sets:"
1692   dmraid_wrapper -r
1693 }
1694 # }}}
1695
1696 # {{{ LVM (Logical Volumes)
1697 config_lvm(){
1698   [ -n "$INSTALLED" ] && return 0
1699
1700   if checkbootparam 'nolvm' ; then
1701      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1702   else
1703     if ! [ -x /sbin/lvm ] ; then
1704        eerror "LVM not available, can not execute it." ; eend 1
1705     else
1706        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1707           einfo "You seem to have logical volumes (LVM) on your system."
1708           eindent
1709           if $SYSTEMD ; then
1710             einfo "Just run 'Start lvm2-pvscan@name' to activate LV or VG 'name' or boot using 'lvm' as bootoption for autostart."
1711           else
1712             einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1713           fi
1714           eend 0
1715           if checkbootparam 'lvm' ; then
1716              if $SYSTEMD ; then
1717                einfo "Bootoption LVM found, enabling related services."
1718                if [ -r /etc/init.d/lvm2-lvmetad ] ; then
1719                  service_wrapper lvm2-lvmetad start ; eend $?
1720                fi
1721                if [ -r /etc/init.d/lvm2-lvmpolld ] ; then
1722                  service_wrapper lvm2-lvmpolld start ; eend $?
1723                fi
1724                einfo "Searching for logical volumes and enabling them:"
1725                vgchange -ay ; eend $?
1726              else
1727                einfo "Bootoption LVM found. Searching for logical volumes and enabling them:"
1728                service_wrapper lvm2 start ; eend $?
1729              fi
1730           fi
1731           eoutdent
1732        fi
1733     fi # check for lvm binary
1734   fi # check for bootoption nolvm
1735 }
1736 # }}}
1737
1738 # {{{ debnet: setup network based on an existing one found on a partition
1739 config_debnet(){
1740 if checkbootparam 'debnet' ; then
1741  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1742  /usr/sbin/debnet
1743 fi
1744 }
1745 # }}}
1746
1747 # {{{ disable console blanking
1748 config_blanking(){
1749 if checkbootparam 'noblank' ; then
1750   einfo "Bootoption noblank found. Disabling monitor blanking."
1751   setterm -blank 0 ; eend $?
1752 fi
1753 }
1754 # }}}
1755
1756 # {{{ debootstrap: automatic installation
1757 config_debootstrap(){
1758
1759 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
1760
1761 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
1762
1763 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
1764    eindent
1765    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
1766    eoutdent
1767    exit 1
1768 fi
1769
1770 if checkbootparam 'target' ; then
1771   TARGET=''
1772   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
1773   # notice: the following checks whether the given partition is available, if not the skip
1774   # execution of grml-debootstrap as it might result in data loss...
1775   if ! [ -r "$TARGET" ] ; then
1776      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
1777   fi
1778 else
1779   eindent
1780   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
1781   eoutdent
1782   exit 1
1783 fi
1784
1785 if checkbootparam 'grub' ; then
1786   GRUB=''
1787   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
1788 fi
1789
1790 if checkbootparam 'groot' ; then
1791   GROOT=''
1792   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
1793 fi
1794
1795 if checkbootparam 'release' ; then
1796   RELEASE=''
1797   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
1798 fi
1799
1800 if checkbootparam 'mirror' ; then
1801   MIRROR=''
1802   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
1803 fi
1804
1805 if checkbootparam 'boot_append' ; then
1806   BOOT_APPEND=''
1807   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
1808 fi
1809
1810 if checkbootparam 'password' ; then
1811   PASSWORD=''
1812   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
1813 fi
1814
1815 # now check which options are available
1816 if [ -n "TARGET" ] ; then
1817    TARGETCMD="--target $TARGET"
1818 else
1819    TARGETCMD=''
1820    eindent
1821    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
1822    eoutdent
1823    exit 1
1824 fi
1825 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
1826 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
1827 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
1828 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
1829 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
1830 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
1831
1832 # and finally write script and execute it
1833 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
1834 #!/bin/sh
1835 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
1836 EOF
1837
1838 chmod 750  /usr/bin/grml-debootstrap_noninteractive
1839
1840 screen /usr/bin/grml-debootstrap_noninteractive
1841 einfo "Invoking a shell, just exit to continue booting..."
1842 /bin/zsh
1843
1844 fi # checkbootparam "BOOT_IMAGE=debian2hd
1845 }
1846 # }}}
1847
1848 # {{{ virtualbox shared folders
1849 config_virtualbox_shared_folders() {
1850 if $VIRTUALBOX ; then
1851   einfo "VirtualBox detected, trying to set up Shared Folders."
1852   if ! modinfo vboxsf &>/dev/null ; then
1853     ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
1854     eend 0
1855   elif ! [ -x /usr/sbin/VBoxService ] ; then
1856     ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
1857     eend 0
1858   else
1859     eindent
1860
1861       einfo "Loading vboxsf driver."
1862       lsmod | grep -q vboxsf || modprobe vboxsf
1863       eend $?
1864
1865       einfo "Adjusting /dev/vboxguest."
1866       chown root:vboxsf /dev/vboxguest
1867       chmod 660 /dev/vboxguest
1868       eend $?
1869
1870       config_userfstab
1871
1872       einfo "Adding $fstabuser to group vboxsf."
1873       adduser grml vboxsf &>/dev/null
1874       eend $?
1875
1876       einfo "Starting VBoxService."
1877       VBoxService >/dev/null
1878       eend $?
1879
1880       local vbautomation='automation'
1881       if checkbootparam 'vbautomation'; then
1882         vbautomation="$(getbootparam 'vbautomation' 2>>$DEBUG)"
1883       fi
1884
1885       if ! VBoxControl sharedfolder list | egrep -q "^[0-9]+ - ${vbautomation}$" ; then
1886         ewarn "No automount shared folder '$vbautomation' available"
1887         eend 0
1888       else
1889         einfo "Found automount shared folder '$vbautomation'"
1890         eend 0
1891
1892         local distri="$(getbootparam 'distri' 2>>$DEBUG)"
1893         [ -n "$distri" ] || distri='grml'
1894
1895         local vbox_auto_sf="/media/sf_${vbautomation}"
1896
1897         sleep 1 # ugly but necessary
1898
1899         counter=10
1900         eindent
1901         while ! [ -d "${vbox_auto_sf}" ] && [[ "$counter" != 0 ]]; do
1902           einfo "Waiting another second to retry access to ${vbox_auto_sf}"
1903           sleep 1
1904           counter=$(( counter-1 ))
1905           eend 0
1906         done
1907         eoutdent
1908
1909         if ! [ -d "${vbox_auto_sf}" ] ; then
1910           eerror "Giving up trying to access folder ${vbox_auto_sf} which doesn't seem to exist"
1911           eend 1
1912         else
1913           einfo "Found shared folders automation directory $vbox_auto_sf"
1914           eend 0
1915
1916           eindent
1917           if checkbootparam 'novbautomation' ; then
1918             einfo "Bootoption novbautomation found. Disabling automation script execution."
1919             eend 0
1920           else
1921             if ! [ -x "${vbox_auto_sf}/${distri}" ] ; then
1922               ewarn "Couldn't find an automation script named ${vbox_auto_sf}/${distri}"
1923               eend 1
1924             else
1925               einfo "Executing '${vbox_auto_sf}/${distri}' now:"
1926               "${vbox_auto_sf}/${distri}"
1927               eend $?
1928             fi
1929           fi
1930           eoutdent
1931         fi
1932       fi
1933
1934     eoutdent
1935   fi
1936 fi
1937 }
1938 # }}}
1939
1940 # {{{ Support customization
1941 config_distri(){
1942 if checkbootparam 'distri'; then
1943   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
1944   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
1945      # make sure the desktop.jpg file is not a symlink, so copying does not file then
1946      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
1947      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
1948   fi
1949 fi
1950 }
1951 # }}}
1952
1953 ## END OF FILE #################################################################
1954 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=2