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