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