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