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