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