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