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