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