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