running_under_secureboot: update for efivarfs + new mokutil behavior
[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-setup-linux." ; 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 # helper function to check whether we're running under (enabled) Secure Boot
547 running_under_secureboot() {
548   # systemd does this for us, but if we are not running under systemd then mokutil
549   # doesn't work as needed as it relies on /sys/firmware/efi/efivars (while
550   # /sys/firmware/efi/vars would exist)
551   if ! $SYSTEMD ; then
552     if modprobe efivarfs &>/dev/null ; then
553       mount -t efivarfs efivarfs /sys/firmware/efi/efivars
554     fi
555   fi
556
557   if [[ -x "$(command -v mokutil)" ]] ; then
558     if mokutil --sb-state 2>/dev/null | grep -q 'SecureBoot enabled' ; then
559       return 0
560     else
561       return 1
562     fi
563   else
564     if modprobe efivarfs &>/dev/null ; then
565       if od -An -t u1 /sys/firmware/efi/vars/SecureBoot-*/data 2>/dev/null | grep -q 1 ; then
566         return 0
567       else
568         return 1
569       fi
570     fi
571   fi
572 }
573
574 config_secureboot(){
575   if running_under_secureboot ; then
576       einfo "SecureBoot is enabled" ; eend 0
577   else
578       einfo "SecureBoot not detected" ; eend 0
579   fi
580 }
581 # }}}
582
583 # {{{ timezone
584 config_timezone(){
585  # don't touch the files if running from harddisk:
586  if [ -z "$INSTALLED" ]; then
587     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
588     if [ -n "$KTZ" ] ; then
589        if [ ! -f "/usr/share/zoneinfo/$KTZ" ]
590        then
591           ewarn "Warning: unknown timezone $KTZ"; eend 0
592        else
593           einfo "Setting timezone."
594           # update debconf
595           area=$(echo $KTZ | cut -d '/' -f1)
596           zone=$(echo $KTZ | cut -d '/' -f2)
597           echo "tzdata tzdata/Areas       select $area" | debconf-set-selections
598           echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections
599           # update files
600           echo $KTZ > /etc/timezone
601           rm -f /etc/localtime
602           cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $?
603        fi
604     fi
605  fi
606 }
607 # }}}
608
609 # activate serial console {{{
610 config_console(){
611 if checkbootparam 'console'; then
612   # this hack is no longer necessary with systemd
613   if $SYSTEMD ; then
614     return
615   fi
616
617   local line
618   local ws
619   ws='   '
620
621   einfo "Bootoption for serial console detected:"
622
623   line="$CMDLINE x "
624   this=""
625   line="${line#*[$ws]}"
626   local telinitq=""
627   while [ -n "$line" ]; do
628     case "$this" in
629       console=*)
630         local serial="$this"
631         local device="${this%%,*}"
632         local device="${device##*=}"
633         if echo $serial | grep -q ttyS ; then
634           local option="${serial##*,}"
635           # default (works for kvm & CO):
636           local speed="115200,57600,38400,19200,9600,4800,2400,1200";
637           # ... unless overriden by command line:
638           case "$option" in
639             115200*) speed=115200 ;;
640              57600*) speed=57600 ;;
641              38400*) speed=38400 ;;
642              19200*) speed=19200 ;;
643               9600*) speed=9600 ;;
644               4800*) speed=4800 ;;
645               2400*) speed=2400 ;;
646               1200*) speed=1200 ;;
647           esac
648           eindent
649             einfo "Activating console login on device ${device} with speed ${speed}."
650             local number="${device#ttyS}"
651             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
652             eend $?
653             telinitq="1"
654           eoutdent
655         fi
656         ;;
657     esac
658     this="${line%%[$ws]*}"
659     line="${line#*[$ws]}"
660   done
661
662   if [ -n "$telinitq" ]; then
663     /sbin/telinit q
664   fi
665   eend $?
666 fi
667 }
668 # }}}
669
670 # {{{ CD Checker
671 config_testcd(){
672 if checkbootparam 'testcd' ; then
673   einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
674   eindent
675
676   local ERROR=true
677   local FOUND_FILE=false
678   local logfile='/tmp/md5sum.log'
679
680   rm -f "$logfile"
681
682   for md5 in $(find "${LIVECD_PATH}" -name md5sums) ; do
683     einfo "Checking files against $md5, this may take a while..."
684
685     FOUND_FILE=true
686     OLD_PWD=$(pwd)
687     cd $(dirname "$md5")
688     md5sum -c $(basename "$md5") |& tee -a "${logfile}"
689     if [ $pipestatus[1] -eq 0 ] ; then
690       ERROR=false
691     fi
692     cd "${OLD_PWD}"
693   done
694
695   if ! $FOUND_FILE ; then
696     eerror 'Error: Could not find md5sum file' ; eend 1
697     return
698   fi
699
700   if ! $ERROR ; then
701     einfo "Everything looks OK" ; eend 0
702   else
703     eerror 'Checksum failed for theses files:' ; eend 1
704     egrep -v '(^md5sum:|OK$)' "${logfile}"
705     eerror 'Data on the medium is possibly incomplete/damaged or RAM of your system is broken.' ; eend 1
706     einfon "Hit return to continue, or press the power button to shut down system."
707     read a
708   fi
709
710   eoutdent
711 fi
712 }
713 # }}}
714
715 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
716 config_blacklist(){
717 if checkbootparam 'blacklist' ; then
718  if [ -z "$INSTALLED" ]; then
719   einfo "Bootoption blacklist found."
720   BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
721   BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
722   if [ -n "$BLACK" ] ; then
723     for module in $(echo ${BLACK//,/ }) ; do
724         einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
725         echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
726         echo "blacklist $module"     >> "$BLACKLIST_FILE"
727         echo "alias     $module off" >> "$BLACKLIST_FILE"
728         echo "# end   entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
729     done
730   else
731    eerror "No given module for blacklist found. Blacklisting will not work therefore."
732   fi
733  else
734   ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
735   eindent
736    einfo "Please blacklist the module(s) manually using the 'blacklist' script."
737   eoutdent
738  fi
739 fi
740 }
741 # }}}
742
743 # {{{ ACPI
744 config_acpi(){
745   if $SYSTEMD ; then
746     echo "systemd detected, no acpi(d) stuff needed." >>"$DEBUG"
747     return
748   fi
749
750   if checkbootparam 'noacpi'; then
751     ewarn "ACPI: Not loading modules as requested by boot option \"noacpi\"." ; eend 0
752   elif checkbootparam 'nogrmlacpi' ; then
753     ewarn "ACPI: Not loading modules as requested by boot option \"nogrmlacpi\"." ; eend 0
754   elif [ ! -d /proc/acpi ] ; then
755     ewarn "ACPI: Kernel support not present." ; eend 0
756   else
757     einfo "ACPI: Loading modules (disable with boot option noacpi / nogrmlacpi): "
758     eindent
759     found=""
760     for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
761       basename="${a##*/}"
762       basename="${basename%%.*}"
763       case "$basename" in *_acpi)
764         egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
765     esac
766     modprobe $basename >>$DEBUG 2>&1 && found="yes"
767     local BASE="$BASE $basename"
768   done
769   if [ -n "$found" ] ; then
770     einfo "$BASE"  ; eend 0
771   else
772     ewarn "(none)" ; eend 1
773   fi
774   if ! pgrep acpid >/dev/null ; then
775     einfo "Starting acpi daemon."
776     service_wrapper acpid.socket start >>$DEBUG 2>&1 ; eend $?
777     service_wrapper acpid start >>$DEBUG 2>&1 ; eend $?
778   else
779     ewarn "acpi daemon already running."
780     eend 0
781   fi
782   eoutdent
783 fi
784 }
785 # }}}
786
787 # {{{ Start brltty
788 config_brltty() {
789   if checkbootparam 'brltty' ; then
790     einfo "Starting brltty service as requested on boot commandline."
791     service_wrapper brltty start ; eend $?
792   fi
793 }
794 # }}}
795
796 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
797 config_fstab(){
798
799 NOSWAP="yes" # we do not use swap by default!
800 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
801    NOSWAP=''
802    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
803 fi
804
805 # Scan for swap, config, homedir - but only in live-mode
806 if [ -z "$INSTALLED" ] ; then
807    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
808    GRML_IMG=""
809    GRML_SWP=""
810    HOMEDIR="$(getbootparam 'home')"
811    if [ -n "$partitions" ]; then
812       while read p m f relax; do
813         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
814         partoptions="users,exec"
815         fnew=""
816         # it's a swap partition?
817         case "$f" in swap)
818           eindent
819           if [ -n "$NOSWAP" ]; then
820              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
821              eend 0
822           else
823              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
824                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
825                      if [ -n "$ANYSWAP" ] ; then
826                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
827                         swapon $p 2>>$DEBUG ; eend $?
828                      else
829                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
830                      fi
831                      ;;
832                    *)
833                      if [[ "$p" == LABEL* ]] ; then
834                         p=$(blkid -t $p | awk -F: '{print $1}')
835                      fi
836                      if grep -q $p /proc/swaps ; then
837                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
838                      else
839                         if [ -b "$p" ] ; then
840                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
841                         swapon $p 2>>$DEBUG ; eend $?
842                         else
843                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
844                         fi
845                      fi
846                      ;;
847              esac # dd-check
848           fi # -n "$NOSWAP
849           eoutdent
850           continue
851           ;;
852         esac # it's a swap partition?
853
854         # mount read-only
855         MOUNTOPTS="ro"
856         case "$f" in
857           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
858           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
859           *) continue ;;
860           # *) NONEFOUND='1'; continue ;;
861         esac
862
863         # use a swapfile
864         if [ -z "$NOSWAP" ] ; then
865            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
866            # Activate swapfile, if exists
867            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
868         fi
869         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
870            mount -o remount,rw $m && MOUNTED=1
871            if swapon "$SWAPFILE" 2>>$DEBUG ; then
872               eindent
873                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
874               eoutdent
875               fnew="$SWAPFILE swap swap defaults 0 0"
876               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
877               GRML_SWP="$GRML_SWP $SWAPFILE"
878               eend 0
879            fi
880            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
881         fi
882
883         # use a image as home
884         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
885         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
886            if [ -n "$HOMEDIR" ]; then
887               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
888                  continue
889               fi
890            fi
891            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
892               GRML_IMG="$IMAGE"
893               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
894            fi
895         fi
896         eend 0
897
898         # Umount, if not in use
899         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
900
901       done <<EOT
902       $(cat /etc/fstab)
903 EOT
904    fi # -n $partitions
905 fi # -z $INSTALLED
906 }
907 # }}}
908
909 # {{{ CPU-detection
910 config_cpu(){
911 if checkbootparam 'nocpu'; then
912   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
913   return 0
914 fi
915
916 if [[ $(grep -c processor /proc/cpuinfo) -gt 1 ]] ; then
917    einfo "Found CPU:"
918    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)
919    echo $CPU | sed 's/ \{1,\}/ /g'
920    eend 0
921 else
922    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
923 fi
924 }
925 # }}}
926
927 # {{{ autostart of ssh
928 config_ssh(){
929 if checkbootparam 'ssh' ; then
930    local PASSWD
931    PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
932
933    config_userlocal
934    einfo "Bootoption ssh found, trying to set password for root and user $localuser"
935    [ -z "$localuser" ] && eend 1
936
937    eindent
938    if [ -z "$PASSWD" ] ; then
939      set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0
940    fi
941    eoutdent
942
943    if [ -n "$PASSWD" ] ; then
944       chpass_options=""
945       if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
946         chpass_options="-m"
947       fi
948
949       echo "$localuser:$PASSWD" | chpasswd $chpass_options
950       echo "root:$PASSWD" | chpasswd $chpass_options
951
952       eindent
953       ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
954       eoutdent
955    fi
956
957    einfo "Starting secure shell server in background for root and user $localuser"
958    service_wrapper haveged start >>$DEBUG 2>>$DEBUG
959    service_wrapper rmnologin start >>$DEBUG 2>>$DEBUG
960    service_wrapper ssh start background >>$DEBUG 2>>$DEBUG
961    eend $?
962
963 fi
964 }
965
966 # }}}
967
968 # {{{ display hostkeys of SSH server
969 config_display_ssh_fingerprints() {
970   if ! ls /etc/ssh/ssh_host_\*_key >/dev/null 2>&1 ; then
971     return 0 # no SSH host keys present
972   fi
973
974   einfo "SSH key fingerprints:"
975   for file in /etc/ssh/ssh_host_*_key ; do
976     einfon
977     ssh-keygen -l -f $file
978   done | column -t
979   eend $?
980 }
981 # }}}
982
983 # {{{ autostart of x11vnc
984 config_vnc(){
985 if checkbootparam 'vnc' ; then
986    config_userlocal
987    VNC_PASSWD=''
988    VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)"
989    einfo "Bootoption vnc found, trying to set password for user $localuser."
990    eindent
991    if [ -z "$VNC_PASSWD" ] ; then
992       if [ -x /usr/bin/apg ] ; then
993          VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
994       elif [ -x /usr/bin/gpw ] ; then
995          VNC_PASSWD="$(gpw 1)"
996       elif [ -x /usr/bin/pwgen ] ; then
997          VNC_PASSWD="$(pwgen -1 8)"
998       elif [ -x /usr/bin/hexdump ] ; then
999          VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1000       elif [ -n "$RANDOM" ] ; then
1001          VNC_PASSWD="${localuser}${RANDOM}"
1002       else
1003          VNC_PASSWD=''
1004          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1005          eend 1
1006       fi
1007
1008       if [ -n "$VNC_PASSWD" ] ; then
1009          ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0
1010       fi
1011    fi
1012    eoutdent
1013
1014    # finally check if we have a password we can use:
1015    if [ -n "$VNC_PASSWD" ] ; then
1016
1017       VNCDIR="/home/${localuser}/.vnc"
1018       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1019
1020       if [ ! -x /usr/bin/x11vnc ] ; then
1021          eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package."
1022          eend 1
1023       else
1024          /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $?
1025          /bin/chown -R "$localuser": "$VNCDIR"
1026       fi
1027    fi
1028    if checkbootparam 'vnc_connect' ; then
1029       VNC_CONNECT=''
1030       VNC_CONNECT="$(getbootparam 'vnc_connect' 2>>$DEBUG)"
1031       einfo "Bootoption vnc_connect found, will start vnc with connect to $VNC_CONNECT."
1032       #store the options in a file
1033       VNCDIR="/home/${localuser}/.vnc"
1034       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1035       echo " --connect $VNC_CONNECT " >> $VNCDIR/options
1036    fi
1037 fi
1038 }
1039 # }}}
1040
1041 # {{{ set password for root and default user
1042 config_passwd(){
1043 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1044   local PASSWD
1045   PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1046
1047   config_userlocal
1048   einfo "Bootoption passwd found, trying to set password for root and user $localuser"
1049   [ -z "$localuser" ] && eend 1
1050
1051   eindent
1052   if [ -z "$PASSWD" ] ; then
1053     set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0
1054   fi
1055   eoutdent
1056
1057   if [ -n "$PASSWD" ] ; then
1058     chpass_options=""
1059     if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1060       chpass_options="-m"
1061     fi
1062
1063     echo "$localuser:$PASSWD" | chpasswd $chpass_options
1064     echo "root:$PASSWD" | chpasswd $chpass_options
1065
1066     eindent
1067     ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
1068     eoutdent
1069   fi
1070
1071 fi
1072
1073 if checkbootparam 'encpasswd' >>$DEBUG 2>&1; then
1074   local PASSWD
1075   PASSWD="$(getbootparam 'encpasswd' 2>>$DEBUG)"
1076
1077   if [ -z "$PASSWD" ] ; then
1078     eerror "No hashed password found, can not set password."
1079     eend 1
1080     return
1081   fi
1082
1083   config_userlocal
1084   einfo "Bootoption encpasswd found, trying to set hashed password for root and user $localuser"
1085   [ -z "$localuser" ] && eend 1
1086
1087   if [ -n "$PASSWD" ] ; then
1088     chpass_options="-e"
1089
1090     echo "$localuser:$PASSWD" | chpasswd $chpass_options
1091     echo "root:$PASSWD" | chpasswd $chpass_options
1092
1093     eindent
1094     ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
1095     eoutdent
1096   fi
1097
1098 fi
1099 }
1100 # }}}
1101
1102 # {{{ Sound
1103 config_mixer () {
1104   if ! [ -x /usr/bin/amixer ] ; then
1105     logger -t grml-autoconfig "amixer binary not available"
1106     return
1107   fi
1108
1109   if ! [ -r /proc/asound/cards ] ; then
1110     ewarn "No soundcard present, skipping mixer settings therefore."
1111     eend 0
1112     return
1113   fi
1114
1115   for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do
1116     einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\""
1117     eindent
1118
1119     if checkbootparam 'vol' ; then
1120       VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1121       if [ -z "$VOL" ] ; then
1122         eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)."
1123         VOL='75'
1124         eend 1
1125       fi
1126     else
1127       VOL='75'
1128     fi
1129
1130     if checkbootparam 'nosound' ; then
1131       einfo "Muting sound devices on request."
1132       ERROR=$(amixer -q set Master mute)
1133       RC=$?
1134       if [ -n "$ERROR" ] ; then
1135         eindent
1136         eerror "Problem muting sound devices: $ERROR"
1137         eoutdent
1138       fi
1139       eend $RC
1140     elif [ -z "$INSTALLED" ] ; then
1141       einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1142
1143       if checkbootparam 'micvol' ; then
1144         MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1145         einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1146       else
1147         MICVOL=0
1148       fi
1149
1150       CONTROLS=$(amixer -c $card scontrols | awk -F"Simple mixer control " '{print $2}')
1151       IFSOLD=${IFS:-}
1152       IFS=$'\n'
1153       for CONTROL in ${=CONTROLS} ; do
1154         # such devices can not be controlled with amixer ... unmute
1155         [[ "$CONTROL" == *Console* ]] && continue
1156
1157         if ! echo "${CONTROL}" | grep -q -i "mic" ; then
1158           if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*pswitch' ; then
1159             amixer -c $card -q set "${CONTROL}" unmute
1160           fi
1161           if amixer -c $card sget "${CONTROL}" | grep -q -P 'Capabilities:.*(pvolume| volume)' ; then
1162             amixer -c $card -q set "${CONTROL}" "${VOL}"%
1163           fi
1164         fi
1165
1166         if [ ${MICVOL} -ne 0 ] ; then
1167           if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cswitch' ; then
1168             amixer -c $card -q set "${CONTROL}" unmute
1169           fi
1170           if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cvolume' ; then
1171             amixer -c $card -q set "${CONTROL}" $MICVOL%
1172           fi
1173           eend $?
1174         fi
1175       done
1176       IFS=$IFSOLD
1177     fi # checkbootparam 'nosound'
1178     eoutdent
1179   done
1180 }
1181 # }}}
1182
1183 # {{{ syslog service
1184 config_syslog(){
1185  if checkbootparam 'nosyslog'; then
1186     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1187  else
1188     einfo "Starting rsyslog in background."
1189     service_wrapper rsyslog start >>$DEBUG
1190     eend 0
1191  fi
1192 }
1193 # }}}
1194
1195 # {{{ gpm
1196 config_gpm(){
1197   if checkbootparam 'nogpm'; then
1198     ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1199   else
1200     if ! [ -r /dev/input/mice ] ; then
1201       eerror "No mouse found - not starting GPM." ; eend 1
1202     else
1203       einfo "Starting gpm in background."
1204       service_wrapper gpm start background >>$DEBUG
1205       eend 0
1206     fi
1207   fi
1208 }
1209 # }}}
1210
1211 # {{{ services
1212 config_services(){
1213  if checkbootparam 'services' ; then
1214     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1215     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1216     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1217     for service in $(echo -e $SERVICELIST) ; do
1218       # support running (custom) init scripts in non-blocking mode
1219       # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1220       if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1221         einfo "Starting service ${service}."
1222         service_wrapper "${service}" start >>$DEBUG
1223       else
1224         einfo "Starting service ${service} in background."
1225         service_wrapper "${service}" start background >>$DEBUG
1226       fi
1227     done
1228     eend $?
1229  fi
1230 }
1231 # }}}
1232
1233 # {{{ remote files
1234 get_remote_file() {
1235   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1236   SOURCE=$(eval echo "$1")
1237   TARGET="$2"
1238   getconfig() {
1239   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1240        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1241   }
1242   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1243
1244   if checkbootparam 'getfile.retries' ; then
1245     local counter="$(getbootparam 'getfile.retries' 2>>$DEBUG)"
1246   else
1247     local counter=10
1248   fi
1249
1250   while ! getconfig && [[ "$counter" != 0 ]] ; do
1251     echo -n "Sleeping for 1 second and trying to get config again... "
1252     counter=$(( counter-1 ))
1253     echo "$counter tries left" ; sleep 1
1254   done
1255   if [ -s "$TARGET" ] ; then
1256     einfo "Downloading was successfull." ; eend 0
1257     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1258     md5sum ${TARGET} ; eend 0
1259     return 0;
1260   else
1261     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1262     return 1;
1263  fi
1264 }
1265 # }}}
1266
1267 # {{{ config files
1268 config_netconfig(){
1269  if checkbootparam 'netconfig' ; then
1270   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1271   CONFIGFILE='/tmp/netconfig.grml'
1272
1273   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1274     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1275   fi
1276
1277  fi
1278 }
1279 # }}}
1280
1281 # {{{ remote scripts
1282 config_netscript() {
1283  if checkbootparam 'netscript' ; then
1284   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1285   SCRIPTFILE='/tmp/netscript.grml'
1286
1287   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1288     chmod +x ${SCRIPTFILE}
1289     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1290   fi
1291
1292  fi
1293 }
1294 # }}}
1295
1296 # {{{ start X window system via grml-x
1297 config_x_startup(){
1298
1299
1300 # make sure we start X only if startx is used *before* a nostartx option
1301 # so it's possible to disable automatic X startup using nostart
1302 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1303  if [ -x "$(which X)" ] ; then
1304   if [ -z "$INSTALLED" ] ; then
1305    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1306    if [ -z "$WINDOWMANAGER" ] ; then
1307      einfo "No window manager specified. Using default one." && eend 0
1308    else
1309      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1310    fi
1311    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1312    config_userlocal
1313    if $SYSTEMD ; then
1314      if [ -n "$WINDOWMANAGER" ] ; then
1315        mkdir -p /var/run/grml-x/
1316        echo "$WINDOWMANAGER" > /var/run/grml-x/window-manager
1317      fi
1318      chvt 7
1319      return
1320    fi
1321    cat>|/etc/init.d/startx<<EOF
1322 #!/bin/sh
1323 su "${localuser}" -c "/usr/bin/grml-x ${WINDOWMANAGER}"
1324 EOF
1325    chmod 755 /etc/init.d/startx
1326
1327    # adjust inittab for startx
1328    if grep -q '^6:' /etc/inittab ; then
1329       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
1330    else # just append tty6 to inittab if no definition is present:
1331       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
1332    fi
1333
1334    /sbin/telinit q ; eend $?
1335
1336    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1337       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1338    else
1339       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1340    fi
1341
1342   else
1343     eerror "We are not running in live mode - startx will not work, skipping it."
1344     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1345   fi
1346  else
1347    eerror "/usr/bin/X is not present on this grml flavour."
1348    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1349  fi
1350 fi
1351 }
1352 # }}}
1353
1354 # {{{ configuration framework
1355 config_extract(){
1356 if checkbootparam 'extract' ; then
1357  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1358  EXTRACTOPTIONS="-- -x $EXTRACT"
1359 fi
1360 }
1361
1362 config_finddcsdir() {
1363 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1364 #    on the command line, nothing is changed and the dcs files are
1365 #    searched within the .iso, $dcs-dir is set to the root directory
1366 #    within the .iso
1367 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1368 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1369 #    set, $dcs-dir is set to the root directory within the .iso.
1370 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1371 #    foo, even if a GRMLCFG partition is present.
1372 DCSDIR=""
1373 DCSMP="/mnt/grml"
1374 # autoconfig, see issue673
1375 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1376 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1377 if checkbootparam 'noautoconfig' ; then
1378   DCSDIR="${LIVECD_PATH}" # set default so it works for "scripts" boot option as expected
1379   ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1380 else
1381   if [ -z "$INSTALLED" ] ; then
1382     if checkbootparam 'myconfig' ; then
1383       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1384       if [ -z "$DCSDEVICE" ]; then
1385         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1386       fi # [ -z "$DCSDEVICE" ]
1387     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1388       einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1389       eindent
1390       DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1391
1392       modprobe 9p 2>/dev/null || true
1393       if [ -z "$DCSDEVICE" ] && grep -q 9p /proc/filesystems ; then
1394           if grep -q "$GRMLCFG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then
1395             einfo "Found 9p-virtio fs with mount_tag $GRMLCFG"
1396             DCSDEVICE="$GRMLCFG"
1397             MOUNTOPTIONS="ro,trans=virtio"
1398             DCSFS="9p"
1399           fi
1400       fi
1401
1402       if [ -n "$DCSDEVICE" ]; then
1403         DCSMP="/mnt/grmlcfg"
1404       fi
1405       eoutdent
1406     fi
1407
1408     # if not specified/present then assume default:
1409     if [ -z "$DCSDEVICE" ]; then
1410       DCSDIR="${LIVECD_PATH}"
1411     else
1412       eindent
1413       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1414       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1415       if [ -n "$DCSDIR" ]; then
1416         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1417       else
1418         [ -d $DCSMP ] || mkdir $DCSMP
1419         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1420         mount -o ${MOUNTOPTIONS:-ro} -t ${DCSFS:-auto} $DCSDEVICE  $DCSMP ; RC="$?"
1421         if [[ $RC == 0 ]]; then
1422           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1423         else
1424           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1425         fi
1426         DCSDIR="$DCSMP"
1427       fi
1428       eoutdent
1429     fi
1430   fi
1431 fi
1432
1433 if [ -n "$DCSDIR" -a "$DCSDIR" != "${LIVECD_PATH}" ] ; then
1434   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1435 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1436   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1437 fi
1438 }
1439
1440
1441 config_partconf() {
1442 if checkbootparam 'partconf' ; then
1443  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1444  if [ -n "$MOUNTDEVICE" ]; then
1445    [ -d /mnt/grml ] || mkdir /mnt/grml
1446    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1447     if [[ $RC == 0 ]]; then
1448       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1449       einfo "Copying files from $MOUNTDEVICE over grml system."
1450       for file in `cat /etc/grml/partconf` ; do
1451         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1452         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1453       done && eend 0
1454     else
1455       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1456     fi # mount $MOUNTDEVICE
1457    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1458  else
1459    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1460  fi # [ -n "$MOUNTDEVICE" ]
1461 fi
1462 }
1463 # }}}
1464
1465 # {{{ /cdrom/.*-options
1466 config_debs(){
1467 if checkbootparam 'debs' ; then
1468    iszsh && setopt localoptions shwordsplit
1469    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1470    if [ -z "$DEBS" ] ; then
1471       DEBS="*.deb"
1472    fi
1473    if ! echo $DEBS | grep -q '/'; then
1474      # backwards compatibility: if no path is given get debs from debs/
1475      DEBS="debs/$DEBS"
1476    fi
1477    einfo "Trying to install Debian package(s) ${DEBS}"
1478    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1479    dpkg -i $DEBS ; eend $?
1480 fi
1481 }
1482
1483 config_scripts(){
1484 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1485    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1486    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1487      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1488    fi
1489    if ! echo $SCRIPTS | grep -q '/'; then
1490      # backwards compatibility: if no path is given get scripts from scripts/
1491      SCRIPTS="scripts/$SCRIPTS"
1492    fi
1493    if [ -n "$SCRIPTS" ]; then
1494      SCRIPTS="${DCSDIR}/$SCRIPTS"
1495      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1496        einfo "Trying to execute ${SCRIPTS}"
1497        sh -c $SCRIPTS
1498        eend $?
1499      elif [ -d "$SCRIPTS" ]; then
1500        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1501        run-parts --regex '.*' $SCRIPTS
1502        eend $?
1503      else
1504        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1505        sh -c $SCRIPTS
1506        eend $?
1507      fi
1508    fi
1509 fi
1510 }
1511
1512 config_config(){
1513 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1514   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1515   if [ -z "$CONFIG" ]; then
1516     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1517   fi
1518   if [ -n "$CONFIG" ]; then
1519     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1520       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1521
1522       cp -a ${DCSDIR}/${CONFIG}/* /
1523     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1524       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1525
1526       cd /
1527       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1528     else
1529       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1530     fi
1531   fi
1532 fi
1533 }
1534 # }}}
1535
1536 # {{{ confing_umount_dcsdir
1537 config_umount_dcsdir(){
1538    # umount $DCSMP if it was mounted by finddcsdir
1539    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1540 }
1541 # }}}
1542
1543 # {{{ mypath
1544 config_mypath(){
1545 if checkbootparam 'mypath' ; then
1546    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1547    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1548    touch /etc/grml/my_path
1549    chmod 644 /etc/grml/my_path
1550    # make sure the directories exist:
1551    eindent
1552    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1553        if ! [ -d "$i" ] ; then
1554           einfo "Creating directory $i"
1555           mkdir -p "$i" ; eend $?
1556        fi
1557    done
1558    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1559    eoutdent
1560 fi
1561 }
1562 # }}}
1563
1564 # {{{ SW-RAID
1565 config_swraid(){
1566   [ -n "$INSTALLED" ] && return 0
1567
1568   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1569      checkbootparam 'raid=noautodetect' ; then
1570      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1571   else
1572     [ -e /proc/mdstat ] || modprobe md_mod
1573     if ! [ -x /sbin/mdadm ] ; then
1574        eerror "mdadm not available, can not execute it." ; eend 1
1575     else
1576
1577        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1578        # find out whether we have a valid configuration file already
1579        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1580           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1581           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1582           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1583         else
1584           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1585        fi
1586
1587        if ! checkbootparam 'swraid' ; then
1588           eindent
1589           if $SYSTEMD ; then
1590             einfo "Just run 'mdadm --assemble --scan' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1591           else
1592             einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1593           fi
1594           eoutdent
1595        else
1596           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1597           eindent
1598            IFSOLD=${IFS:-}
1599            IFS=$'\n'
1600            for line in $(mdadm --assemble --scan 2>&1) ; do
1601                case $line in
1602                  *'No arrays found'*)
1603                    ewarn "$line" ; eend 0
1604                    ;;
1605                  *)
1606                    einfo "$line" ; eend 0
1607                    ;;
1608                esac
1609            done
1610            IFS=$IFSOLD
1611          eoutdent
1612
1613          if [ -r /proc/mdstat ] ; then
1614             eindent
1615             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1616             if [ -z "$MDSTAT" ] ; then
1617                ewarn "No active arrays found" ; eend 0
1618             else
1619                IFSOLD=${IFS:-}
1620                IFS=$'\n'
1621                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1622                    einfo "active arrays: $line" ; eend 0
1623                done
1624                IFS=$IFSOLD
1625             fi
1626             eoutdent
1627          fi # /proc/mdstat
1628        fi # bootoption swraid
1629
1630      fi # is /sbin/mdadm executable?
1631   fi # check for bootoptions
1632 }
1633 # }}}
1634
1635 # {{{ dmraid
1636 config_dmraid(){
1637   [ -n "$INSTALLED" ] && return 0
1638
1639   if checkbootparam 'nodmraid' ; then
1640     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1641     return 0
1642   fi
1643
1644   if ! [ -x /sbin/dmraid ] ; then
1645     ewarn "dmraid not available, can not execute it." ; eend 1
1646     return
1647   fi
1648
1649   dmraid_wrapper() {
1650     # usage: dmraid_wrapper <dmraid_option>
1651     [ -n "$1" ] || return 1
1652
1653     IFSOLD=${IFS:-}
1654     IFS=$'\n'
1655     eindent
1656
1657     for line in $(dmraid $1 ; echo errcode:$?); do
1658       case $line in
1659         *'no block devices found'*)
1660           einfo "No block devices found" ; eend 0
1661           break
1662           ;;
1663         *'no raid disks'*)
1664           einfo "No active dmraid devices found" ; eend 0
1665           break
1666           ;;
1667         errcode:0)
1668           eend 0;
1669           ;;
1670         errcode:1)
1671           eend 1
1672           ;;
1673         *)
1674           einfo "$line"
1675           ;;
1676       esac
1677     done
1678
1679     eoutdent
1680     IFS=$IFSOLD
1681   }
1682
1683   if checkbootparam 'dmraid' ; then
1684     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1685     if [ "$ACTION" = "off" ] ; then
1686       # Deactivates all active software RAID sets:
1687       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1688       dmraid_wrapper -an
1689     else
1690       # Activate all software RAID sets discovered:
1691       einfo "Activating present dmraid sets (as requested via dmraid):"
1692       dmraid_wrapper -ay
1693     fi
1694
1695     return
1696   fi
1697
1698   # by default (no special bootoptions) discover all software RAID devices:
1699   einfo "Searching for any present dmraid sets:"
1700   dmraid_wrapper -r
1701 }
1702 # }}}
1703
1704 # {{{ LVM (Logical Volumes)
1705 config_lvm(){
1706   [ -n "$INSTALLED" ] && return 0
1707
1708   if checkbootparam 'nolvm' ; then
1709      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1710   else
1711     if ! [ -x /sbin/lvm ] ; then
1712        eerror "LVM not available, can not execute it." ; eend 1
1713     else
1714        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1715           einfo "You seem to have logical volumes (LVM) on your system."
1716           eindent
1717           if $SYSTEMD ; then
1718             einfo "Just run 'Start lvm2-pvscan@name' to activate LV or VG 'name' or boot using 'lvm' as bootoption for autostart."
1719           else
1720             einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1721           fi
1722           eend 0
1723           if checkbootparam 'lvm' ; then
1724              if $SYSTEMD ; then
1725                einfo "Bootoption LVM found, enabling related services."
1726                if [ -r /etc/init.d/lvm2-lvmetad ] ; then
1727                  service_wrapper lvm2-lvmetad start ; eend $?
1728                fi
1729                if [ -r /etc/init.d/lvm2-lvmpolld ] ; then
1730                  service_wrapper lvm2-lvmpolld start ; eend $?
1731                fi
1732                einfo "Searching for logical volumes and enabling them:"
1733                vgchange -ay ; eend $?
1734              else
1735                einfo "Bootoption LVM found. Searching for logical volumes and enabling them:"
1736                service_wrapper lvm2 start ; eend $?
1737              fi
1738           fi
1739           eoutdent
1740        fi
1741     fi # check for lvm binary
1742   fi # check for bootoption nolvm
1743 }
1744 # }}}
1745
1746 # {{{ debnet: setup network based on an existing one found on a partition
1747 config_debnet(){
1748 if checkbootparam 'debnet' ; then
1749  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1750  /usr/sbin/debnet
1751 fi
1752 }
1753 # }}}
1754
1755 # {{{ disable console blanking
1756 config_blanking(){
1757 if checkbootparam 'noblank' ; then
1758   einfo "Bootoption noblank found. Disabling monitor blanking."
1759   setterm -blank 0 ; eend $?
1760 fi
1761 }
1762 # }}}
1763
1764 # {{{ debootstrap: automatic installation
1765 config_debootstrap(){
1766
1767 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
1768
1769 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
1770
1771 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
1772    eindent
1773    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
1774    eoutdent
1775    exit 1
1776 fi
1777
1778 if checkbootparam 'target' ; then
1779   TARGET=''
1780   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
1781   # notice: the following checks whether the given partition is available, if not the skip
1782   # execution of grml-debootstrap as it might result in data loss...
1783   if ! [ -r "$TARGET" ] ; then
1784      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
1785   fi
1786 else
1787   eindent
1788   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
1789   eoutdent
1790   exit 1
1791 fi
1792
1793 if checkbootparam 'grub' ; then
1794   GRUB=''
1795   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
1796 fi
1797
1798 if checkbootparam 'groot' ; then
1799   GROOT=''
1800   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
1801 fi
1802
1803 if checkbootparam 'release' ; then
1804   RELEASE=''
1805   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
1806 fi
1807
1808 if checkbootparam 'mirror' ; then
1809   MIRROR=''
1810   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
1811 fi
1812
1813 if checkbootparam 'boot_append' ; then
1814   BOOT_APPEND=''
1815   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
1816 fi
1817
1818 if checkbootparam 'password' ; then
1819   PASSWORD=''
1820   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
1821 fi
1822
1823 # now check which options are available
1824 if [ -n "TARGET" ] ; then
1825    TARGETCMD="--target $TARGET"
1826 else
1827    TARGETCMD=''
1828    eindent
1829    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
1830    eoutdent
1831    exit 1
1832 fi
1833 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
1834 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
1835 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
1836 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
1837 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
1838 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
1839
1840 # and finally write script and execute it
1841 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
1842 #!/bin/sh
1843 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
1844 EOF
1845
1846 chmod 750  /usr/bin/grml-debootstrap_noninteractive
1847
1848 screen /usr/bin/grml-debootstrap_noninteractive
1849 einfo "Invoking a shell, just exit to continue booting..."
1850 /bin/zsh
1851
1852 fi # checkbootparam "BOOT_IMAGE=debian2hd
1853 }
1854 # }}}
1855
1856 # {{{ virtualbox shared folders
1857 config_virtualbox_shared_folders() {
1858   if ! $VIRTUALBOX ; then
1859     return
1860   fi
1861
1862   if checkbootparam 'novboxsf' ; then
1863     ewarn "Skipping VirtualBox Shared Folders setup as requested on boot commandline." ; eend 0
1864   else
1865     einfo "VirtualBox detected, trying to set up Shared Folders."
1866     if ! modinfo vboxsf &>/dev/null ; then
1867       ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
1868       eend 0
1869     elif ! [ -x /usr/sbin/VBoxService ] ; then
1870       ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
1871       eend 0
1872     else
1873       eindent
1874
1875       einfo "Loading vboxsf driver."
1876       lsmod | grep -q vboxsf || modprobe vboxsf
1877       eend $?
1878
1879       einfo "Adjusting /dev/vboxguest."
1880       chown root:vboxsf /dev/vboxguest
1881       chmod 660 /dev/vboxguest
1882       eend $?
1883
1884       config_userfstab
1885
1886       einfo "Adding user ${fstabuser:-grml} to group vboxsf."
1887       adduser "${fstabuser:-grml}" vboxsf >>"${DEBUG}" 2>&1
1888       eend $?
1889
1890       einfo "Starting VBoxService."
1891       VBoxService >/dev/null
1892       eend $?
1893
1894       local vbautomation='automation'
1895       if checkbootparam 'vbautomation'; then
1896         vbautomation="$(getbootparam 'vbautomation' 2>>$DEBUG)"
1897       fi
1898
1899       if ! VBoxControl sharedfolder list | egrep -q "^[0-9]+ - ${vbautomation}(\s+|$)" ; then
1900         ewarn "No automount shared folder '$vbautomation' available"
1901         eend 0
1902       else
1903         einfo "Found automount shared folder '$vbautomation'"
1904         eend 0
1905
1906         local distri="$(getbootparam 'distri' 2>>$DEBUG)"
1907         [ -n "$distri" ] || distri='grml'
1908
1909         local vbox_auto_sf="/media/sf_${vbautomation}"
1910
1911         sleep 1 # ugly but necessary
1912
1913         counter=10
1914         eindent
1915         while ! [ -d "${vbox_auto_sf}" ] && [[ "$counter" != 0 ]]; do
1916           einfo "Waiting another second to retry access to ${vbox_auto_sf}"
1917           sleep 1
1918           counter=$(( counter-1 ))
1919           eend 0
1920         done
1921         eoutdent
1922
1923         if ! [ -d "${vbox_auto_sf}" ] ; then
1924           eerror "Giving up trying to access folder ${vbox_auto_sf} which doesn't seem to exist"
1925           eend 1
1926         else
1927           einfo "Found shared folders automation directory $vbox_auto_sf"
1928           eend 0
1929
1930           eindent
1931           if checkbootparam 'novbautomation' ; then
1932             einfo "Bootoption novbautomation found. Disabling automation script execution."
1933             eend 0
1934           else
1935             if ! [ -x "${vbox_auto_sf}/${distri}" ] ; then
1936               ewarn "Couldn't find an automation script named ${vbox_auto_sf}/${distri}"
1937               eend 1
1938             else
1939               einfo "Executing '${vbox_auto_sf}/${distri}' now:"
1940               "${vbox_auto_sf}/${distri}"
1941               eend $?
1942             fi
1943           fi
1944           eoutdent
1945         fi
1946       fi
1947
1948       eoutdent
1949     fi
1950   fi
1951 }
1952 # }}}
1953
1954 # {{{ VirtualBox application
1955 config_virtualbox_setup() {
1956   if checkbootparam 'novbox' ; then
1957     ewarn "Skipping VirtualBox setup as requested on boot commandline." ; eend 0
1958     return
1959   fi
1960
1961   if ! [ -x /usr/bin/VBox ] ; then
1962     return
1963   fi
1964
1965   if running_under_secureboot ; then
1966     ewarn "VirtualBox service can not be started as running under enabled Secure Boot." ; eend 0
1967     return
1968   fi
1969
1970   einfo "VirtualBox service detected, trying to set up."
1971   service_wrapper vboxdrv restart >>"${DEBUG}" 2>&1 ; eend $?
1972
1973   config_userfstab
1974
1975   einfo "Adding user ${fstabuser:-grml} to group vboxusers."
1976   adduser "${fstabuser:-grml}" vboxusers >>"${DEBUG}" 2>&1
1977   eend $?
1978 }
1979 # }}}
1980
1981 # {{{ Support customization
1982 config_distri(){
1983 if checkbootparam 'distri'; then
1984   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
1985   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
1986      # make sure the desktop.jpg file is not a symlink, so copying does not file then
1987      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
1988      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
1989   fi
1990 fi
1991 }
1992 # }}}
1993
1994 ## END OF FILE #################################################################
1995 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=2