Build-Depend on debhlper >= 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 # {{{ 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 # {{{ timezone
544 config_timezone(){
545  # don't touch the files if running from harddisk:
546  if [ -z "$INSTALLED" ]; then
547     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
548     if [ -n "$KTZ" ] ; then
549        if [ ! -f "/usr/share/zoneinfo/$KTZ" ]
550        then
551           ewarn "Warning: unknown timezone $KTZ"; eend 0
552        else
553           einfo "Setting timezone."
554           # update debconf
555           area=$(echo $KTZ | cut -d '/' -f1)
556           zone=$(echo $KTZ | cut -d '/' -f2)
557           echo "tzdata tzdata/Areas       select $area" | debconf-set-selections
558           echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections
559           # update files
560           echo $KTZ > /etc/timezone
561           rm -f /etc/localtime
562           cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $?
563        fi
564     fi
565  fi
566 }
567 # }}}
568
569 # activate serial console {{{
570 config_console(){
571 if checkbootparam 'console'; then
572   local line
573   local ws
574   ws='   '
575
576   einfo "Bootoption for serial console detected:"
577
578   line="$CMDLINE x "
579   this=""
580   line="${line#*[$ws]}"
581   local telinitq=""
582   while [ -n "$line" ]; do
583     case "$this" in
584       console=*)
585         local serial="$this"
586         local device="${this%%,*}"
587         local device="${device##*=}"
588         if echo $serial | grep -q ttyS ; then
589           local option="${serial##*,}"
590           # default (works for kvm & CO):
591           local speed="115200,57600,38400,19200,9600,4800,2400,1200";
592           # ... unless overriden by command line:
593           case "$option" in
594             115200*) speed=115200 ;;
595              57600*) speed=57600 ;;
596              38400*) speed=38400 ;;
597              19200*) speed=19200 ;;
598               9600*) speed=9600 ;;
599               4800*) speed=4800 ;;
600               2400*) speed=2400 ;;
601               1200*) speed=1200 ;;
602           esac
603           eindent
604             einfo "Activating console login on device ${device} with speed ${speed}."
605             local number="${device#ttyS}"
606             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
607             eend $?
608             telinitq="1"
609           eoutdent
610         fi
611         ;;
612     esac
613     this="${line%%[$ws]*}"
614     line="${line#*[$ws]}"
615   done
616
617   if [ -n "$telinitq" ]; then
618     /sbin/telinit q
619   fi
620   eend $?
621 fi
622 }
623 # }}}
624
625 # {{{ CD Checker
626 config_testcd(){
627 if checkbootparam 'testcd' ; then
628   einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
629   eindent
630
631   local ERROR=true
632   local FOUND_FILE=false
633   local logfile='/tmp/md5sum.log'
634
635   rm -f "$logfile"
636
637   for md5 in $(find "${LIVECD_PATH}" -name md5sums) ; do
638     einfo "Checking files against $md5, this may take a while..."
639
640     FOUND_FILE=true
641     OLD_PWD=$(pwd)
642     cd $(dirname "$md5")
643     md5sum -c $(basename "$md5") |& tee -a "${logfile}"
644     if [ $pipestatus[1] -eq 0 ] ; then
645       ERROR=false
646     fi
647     cd "${OLD_PWD}"
648   done
649
650   if ! $FOUND_FILE ; then
651     eerror 'Error: Could not find md5sum file' ; eend 1
652     return
653   fi
654
655   if ! $ERROR ; then
656     einfo "Everything looks OK" ; eend 0
657   else
658     eerror 'Checksum failed for theses files:' ; eend 1
659     egrep -v '(^md5sum:|OK$)' "${logfile}"
660     eerror 'Data on the medium is possibly incomplete/damaged or RAM of your system is broken.' ; eend 1
661     einfon "Hit return to continue, or press the power button to shut down system."
662     read a
663   fi
664
665   eoutdent
666 fi
667 }
668 # }}}
669
670 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
671 config_blacklist(){
672 if checkbootparam 'blacklist' ; then
673  if [ -z "$INSTALLED" ]; then
674   einfo "Bootoption blacklist found."
675   BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
676   BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
677   if [ -n "$BLACK" ] ; then
678     for module in $(echo ${BLACK//,/ }) ; do
679         einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
680         echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
681         echo "blacklist $module"     >> "$BLACKLIST_FILE"
682         echo "alias     $module off" >> "$BLACKLIST_FILE"
683         echo "# end   entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
684     done
685   else
686    eerror "No given module for blacklist found. Blacklisting will not work therefore."
687   fi
688  else
689   ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
690   eindent
691    einfo "Please blacklist the module(s) manually using the 'blacklist' script."
692   eoutdent
693  fi
694 fi
695 }
696 # }}}
697
698 # {{{ ACPI
699 config_acpi(){
700 if checkbootparam 'noacpi'; then
701   ewarn "ACPI: Not loading modules as requested by boot option \"noacpi\"." ; eend 0
702 elif checkbootparam 'nogrmlacpi' ; then
703   ewarn "ACPI: Not loading modules as requested by boot option \"nogrmlacpi\"." ; eend 0
704 elif [ ! -d /proc/acpi ] ; then
705   ewarn "ACPI: Kernel support not present." ; eend 0
706 else
707   einfo "ACPI: Loading modules (disable with boot option noacpi / nogrmlacpi): "
708   eindent
709   found=""
710   for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
711     basename="${a##*/}"
712     basename="${basename%%.*}"
713     case "$basename" in *_acpi)
714      egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
715     esac
716     modprobe $basename >>$DEBUG 2>&1 && found="yes"
717     local BASE="$BASE $basename"
718   done
719   if [ -n "$found" ] ; then
720     einfo "$BASE"  ; eend 0
721   else
722     ewarn "(none)" ; eend 1
723   fi
724   if ! pgrep acpid >/dev/null ; then
725     einfo "Starting acpi daemon."
726     service_wrapper acpid.socket start >>$DEBUG 2>&1 ; eend $?
727     service_wrapper acpid start >>$DEBUG 2>&1 ; eend $?
728   else
729     ewarn "acpi daemon already running."
730     eend 0
731   fi
732   eoutdent
733 fi
734 }
735 # }}}
736
737 # {{{ Start brltty
738 config_brltty() {
739   if checkbootparam 'brltty' ; then
740     [ -x /lib/brltty/brltty.sh ] && /lib/brltty/brltty.sh
741   fi
742 }
743 # }}}
744
745 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
746 config_fstab(){
747
748 NOSWAP="yes" # we do not use swap by default!
749 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
750    NOSWAP=''
751    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
752 fi
753
754 # Scan for swap, config, homedir - but only in live-mode
755 if [ -z "$INSTALLED" ] ; then
756    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
757    GRML_IMG=""
758    GRML_SWP=""
759    HOMEDIR="$(getbootparam 'home')"
760    if [ -n "$partitions" ]; then
761       while read p m f relax; do
762         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
763         partoptions="users,exec"
764         fnew=""
765         # it's a swap partition?
766         case "$f" in swap)
767           eindent
768           if [ -n "$NOSWAP" ]; then
769              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
770              eend 0
771           else
772              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
773                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
774                      if [ -n "$ANYSWAP" ] ; then
775                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
776                         swapon $p 2>>$DEBUG ; eend $?
777                      else
778                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
779                      fi
780                      ;;
781                    *)
782                      if [[ "$p" == LABEL* ]] ; then
783                         p=$(blkid -t $p | awk -F: '{print $1}')
784                      fi
785                      if grep -q $p /proc/swaps ; then
786                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
787                      else
788                         if [ -b "$p" ] ; then
789                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
790                         swapon $p 2>>$DEBUG ; eend $?
791                         else
792                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
793                         fi
794                      fi
795                      ;;
796              esac # dd-check
797           fi # -n "$NOSWAP
798           eoutdent
799           continue
800           ;;
801         esac # it's a swap partition?
802
803         # mount read-only
804         MOUNTOPTS="ro"
805         case "$f" in
806           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
807           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
808           *) continue ;;
809           # *) NONEFOUND='1'; continue ;;
810         esac
811
812         # use a swapfile
813         if [ -z "$NOSWAP" ] ; then
814            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
815            # Activate swapfile, if exists
816            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
817         fi
818         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
819            mount -o remount,rw $m && MOUNTED=1
820            if swapon "$SWAPFILE" 2>>$DEBUG ; then
821               eindent
822                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
823               eoutdent
824               fnew="$SWAPFILE swap swap defaults 0 0"
825               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
826               GRML_SWP="$GRML_SWP $SWAPFILE"
827               eend 0
828            fi
829            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
830         fi
831
832         # use a image as home
833         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
834         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
835            if [ -n "$HOMEDIR" ]; then
836               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
837                  continue
838               fi
839            fi
840            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
841               GRML_IMG="$IMAGE"
842               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
843            fi
844         fi
845         eend 0
846
847         # Umount, if not in use
848         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
849
850       done <<EOT
851       $(cat /etc/fstab)
852 EOT
853    fi # -n $partitions
854 fi # -z $INSTALLED
855 }
856 # }}}
857
858 # {{{ CPU-detection
859 config_cpu(){
860 if checkbootparam 'nocpu'; then
861   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
862   return 0
863 fi
864
865 if [[ $(grep -c processor /proc/cpuinfo) -gt 1 ]] ; then
866    einfo "Found CPU:"
867    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)
868    echo $CPU | sed 's/ \{1,\}/ /g'
869    eend 0
870 else
871    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
872 fi
873
874 # no cpufreq setup inside VirtualBox
875 if $VIRTUALBOX ; then
876    einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0
877    return 0
878 fi
879
880 if ! [ -x /etc/init.d/loadcpufreq ] ; then
881   ewarn "loadcpufreq init script not available, ignoring cpu frequency scaling."
882   eend 0
883   return 0
884 else
885    einfo "Trying to set up cpu frequency scaling:"
886    eindent
887    SKIP_CPU_GOVERNOR=''
888    LOADCPUFREQ=$(mktemp)
889    /etc/init.d/loadcpufreq start >"$LOADCPUFREQ" 2>&1 ; RC=$?
890    if grep -q FATAL "$LOADCPUFREQ" ; then
891       eindent
892         SKIP_CPU_GOVERNOR=1
893         oldIFS="$IFS"
894         IFS="
895 "
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       eerror "amixer binary not available. Can not set sound volumes therefore."
1111       eend 1
1112    else
1113       if ! [ -r /proc/asound/cards ] ; then
1114          ewarn "No soundcard present, skipping mixer settings therefore."
1115          eend 0
1116          return
1117       fi
1118
1119       for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do
1120          einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\""
1121          eindent
1122
1123          if checkbootparam 'vol' ; then
1124             VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1125             if [ -z "$VOL" ] ; then
1126                eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)."
1127                VOL='75'
1128                eend 1
1129             fi
1130          else
1131             VOL='75'
1132          fi
1133
1134          if checkbootparam 'nosound' ; then
1135             einfo "Muting sound devices on request."
1136             ERROR=$(amixer -q set Master mute)
1137             RC=$?
1138             if [ -n "$ERROR" ] ; then
1139                eindent
1140                eerror "Problem muting sound devices: $ERROR"
1141                eoutdent
1142             fi
1143             eend $RC
1144          elif [ -z "$INSTALLED" ] ; then
1145             einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1146
1147             if checkbootparam 'micvol' ; then
1148                MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1149                einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1150             else
1151                MICVOL=0
1152             fi
1153
1154             CONTROLS=$(amixer -c $card scontrols | awk -F"Simple mixer control " '{print $2}')
1155             IFSOLD=${IFS:-}
1156             IFS='
1157 '
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    fi
1186 }
1187 # }}}
1188
1189 # {{{ syslog service
1190 config_syslog(){
1191  if checkbootparam 'nosyslog'; then
1192     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1193  else
1194     einfo "Starting rsyslog in background."
1195     service_wrapper rsyslog start >>$DEBUG &
1196     eend 0
1197  fi
1198 }
1199 # }}}
1200
1201 # {{{ gpm
1202 config_gpm(){
1203  if checkbootparam 'nogpm'; then
1204   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1205  else
1206    if ! [ -r /dev/input/mice ] ; then
1207       eerror "No mouse found - not starting GPM." ; eend 1
1208    else
1209       einfo "Starting gpm in background."
1210       service_wrapper gpm start >>$DEBUG &
1211       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start >>$DEBUG ) &
1212       eend 0
1213    fi
1214  fi
1215 }
1216 # }}}
1217
1218 # {{{ services
1219 config_services(){
1220  if checkbootparam 'services' ; then
1221     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1222     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1223     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1224     for service in $(echo -e $SERVICELIST) ; do
1225       # support running (custom) init scripts in non-blocking mode
1226       # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1227       if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1228         einfo "Starting service ${service}."
1229         service_wrapper "${service}" start >>$DEBUG
1230       else
1231         einfo "Starting service ${service} in background."
1232         service_wrapper "${service}" start >>$DEBUG &
1233       fi
1234     done
1235     eend $?
1236  fi
1237 }
1238 # }}}
1239
1240 # {{{ remote files
1241 get_remote_file() {
1242   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1243   SOURCE=$(eval echo "$1")
1244   TARGET="$2"
1245   getconfig() {
1246   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1247        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1248   }
1249   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1250
1251   if checkbootparam 'getfile.retries' ; then
1252     local counter="$(getbootparam 'getfile.retries' 2>>$DEBUG)"
1253   else
1254     local counter=10
1255   fi
1256
1257   while ! getconfig && [[ "$counter" != 0 ]] ; do
1258     echo -n "Sleeping for 1 second and trying to get config again... "
1259     counter=$(( counter-1 ))
1260     echo "$counter tries left" ; sleep 1
1261   done
1262   if [ -s "$TARGET" ] ; then
1263     einfo "Downloading was successfull." ; eend 0
1264     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1265     md5sum ${TARGET} ; eend 0
1266     return 0;
1267   else
1268     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1269     return 1;
1270  fi
1271 }
1272 # }}}
1273
1274 # {{{ config files
1275 config_netconfig(){
1276  if checkbootparam 'netconfig' ; then
1277   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1278   CONFIGFILE='/tmp/netconfig.grml'
1279
1280   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1281     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1282   fi
1283
1284  fi
1285 }
1286 # }}}
1287
1288 # {{{ remote scripts
1289 config_netscript() {
1290  if checkbootparam 'netscript' ; then
1291   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1292   SCRIPTFILE='/tmp/netscript.grml'
1293
1294   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1295     chmod +x ${SCRIPTFILE}
1296     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1297   fi
1298
1299  fi
1300 }
1301 # }}}
1302
1303 # {{{ stats
1304 config_stats() {
1305  if ! checkbootparam 'nostats' ; then
1306    BASE_URL="http://stats.grml.org/report/"
1307    ACTION_NAME=Boot
1308
1309    HOST_ID=$(cat /proc/sys/kernel/random/boot_id)
1310
1311    grep -q " lm " /proc/cpuinfo && HAS_64BIT="1" || HAS_64BIT="0"
1312    DATE_STRING=$(date +'h=%H&m=%M&s=%S')
1313    [ -e /etc/grml_version ] && VERSION=$(cat /etc/grml_version) || \
1314      VERSION=$(lsb_release -d | awk -F: '{gsub(/^[ \t]+/, "", $2); print $2}')
1315
1316    PARAMS="$( echo "$CMDLINE" | sed -e 's/=[^ ]*/=x/g' | tr " " "\n"|sort|tr "\n" " " )"
1317
1318    echo "$CMDLINE" | grep -q -e "fetch" -e "nfsroot" && BOOT="remote"
1319    [ -z "$BOOT" ] && BOOT="local"
1320
1321    ADDITIONAL_PARAMS=""
1322    ( [ -n "$COLUMNS" ] && [ -n "$LINES" ] ) && \
1323      ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS&res=$((COLUMNS * 8))x$((LINES * 16))"
1324
1325    URI='$BASE_URL?action=${ACTION_NAME}\&$DATE_STRING\&unique_id=${HOST_ID}\&support_64bit=$HAS_64BIT\&version=$VERSION\&bootup=$BOOT\&params=$PARAMS$ADDITIONAL_PARAMS'
1326
1327    get_remote_file "$URI" "/dev/null"  >/dev/null 2>&1 &!
1328  fi
1329 }
1330 # }}}
1331
1332 # {{{ start X window system via grml-x
1333 config_x_startup(){
1334
1335   if $SYSTEMD ; then
1336     ewarn "The startx boot option isn't yet supported via systemd, sorry." ; eend 0
1337     return
1338   fi
1339
1340 # make sure we start X only if startx is used *before* a nostartx option
1341 # so it's possible to disable automatic X startup using nostart
1342 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1343  if [ -x "$(which X)" ] ; then
1344   if [ -z "$INSTALLED" ] ; then
1345    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1346    if [ -z "$WINDOWMANAGER" ] ; then
1347      einfo "No window manager specified. Using default one." && eend 0
1348    else
1349      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1350    fi
1351    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1352    config_userlocal
1353  cat>|/etc/init.d/xstartup<<EOF
1354 #!/bin/sh
1355 su $localuser -c "/usr/bin/grml-x ${WINDOWMANAGER}"
1356 EOF
1357    chmod 755 /etc/init.d/xstartup
1358
1359    # adjust inittab for xstartup
1360    if grep -q '^6:' /etc/inittab ; then
1361       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
1362    else # just append tty6 to inittab if no definition is present:
1363       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
1364    fi
1365
1366    /sbin/telinit q ; eend $?
1367
1368    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1369       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1370    else
1371       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1372    fi
1373
1374   else
1375     eerror "We are not running in live mode - startx will not work, skipping it."
1376     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1377   fi
1378  else
1379    eerror "/usr/bin/X is not present on this grml flavour."
1380    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1381  fi
1382 fi
1383 }
1384 # }}}
1385
1386 # {{{ configuration framework
1387 config_extract(){
1388 if checkbootparam 'extract' ; then
1389  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1390  EXTRACTOPTIONS="-- -x $EXTRACT"
1391 fi
1392 }
1393
1394 config_finddcsdir() {
1395 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1396 #    on the command line, nothing is changed and the dcs files are
1397 #    searched within the .iso, $dcs-dir is set to the root directory
1398 #    within the .iso
1399 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1400 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1401 #    set, $dcs-dir is set to the root directory within the .iso.
1402 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1403 #    foo, even if a GRMLCFG partition is present.
1404 DCSDIR=""
1405 DCSMP="/mnt/grml"
1406 # autoconfig, see issue673
1407 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1408 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1409 if checkbootparam 'noautoconfig' ; then
1410   DCSDIR="${LIVECD_PATH}" # set default so it works for "scripts" boot option as expected
1411   ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1412 else
1413   if [ -z "$INSTALLED" ] ; then
1414     if checkbootparam 'myconfig' ; then
1415       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1416       if [ -z "$DCSDEVICE" ]; then
1417         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1418       fi # [ -z "$DCSDEVICE" ]
1419     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1420       einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1421       eindent
1422       DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1423
1424       modprobe 9p 2>/dev/null || true
1425       if [ -z "$DCSDEVICE" ] && grep -q 9p /proc/filesystems ; then
1426           if grep -q "$GRMLCFG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then
1427             einfo "Found 9p-virtio fs with mount_tag $GRMLCFG"
1428             DCSDEVICE="$GRMLCFG"
1429             MOUNTOPTIONS="ro,trans=virtio"
1430             DCSFS="9p"
1431           fi
1432       fi
1433
1434       if [ -n "$DCSDEVICE" ]; then
1435         DCSMP="/mnt/grmlcfg"
1436       fi
1437       eoutdent
1438     fi
1439
1440     # if not specified/present then assume default:
1441     if [ -z "$DCSDEVICE" ]; then
1442       DCSDIR="${LIVECD_PATH}"
1443     else
1444       eindent
1445       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1446       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1447       if [ -n "$DCSDIR" ]; then
1448         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1449       else
1450         [ -d $DCSMP ] || mkdir $DCSMP
1451         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1452         mount -o ${MOUNTOPTIONS:-ro} -t ${DCSFS:-auto} $DCSDEVICE  $DCSMP ; RC="$?"
1453         if [[ $RC == 0 ]]; then
1454           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1455         else
1456           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1457         fi
1458         DCSDIR="$DCSMP"
1459       fi
1460       eoutdent
1461     fi
1462   fi
1463 fi
1464
1465 if [ -n "$DCSDIR" -a "$DCSDIR" != "${LIVECD_PATH}" ] ; then
1466   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1467 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1468   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1469 fi
1470 }
1471
1472
1473 config_partconf() {
1474 if checkbootparam 'partconf' ; then
1475  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1476  if [ -n "$MOUNTDEVICE" ]; then
1477    [ -d /mnt/grml ] || mkdir /mnt/grml
1478    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1479     if [[ $RC == 0 ]]; then
1480       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1481       einfo "Copying files from $MOUNTDEVICE over grml system."
1482       for file in `cat /etc/grml/partconf` ; do
1483         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1484         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1485       done && eend 0
1486     else
1487       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1488     fi # mount $MOUNTDEVICE
1489    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1490  else
1491    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1492  fi # [ -n "$MOUNTDEVICE" ]
1493 fi
1494 }
1495 # }}}
1496
1497 # {{{ /cdrom/.*-options
1498 config_debs(){
1499 if checkbootparam 'debs' ; then
1500    iszsh && setopt localoptions shwordsplit
1501    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1502    if [ -z "$DEBS" ] ; then
1503       DEBS="*.deb"
1504    fi
1505    if ! echo $DEBS | grep -q '/'; then
1506      # backwards compatibility: if no path is given get debs from debs/
1507      DEBS="debs/$DEBS"
1508    fi
1509    einfo "Trying to install Debian package(s) ${DEBS}"
1510    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1511    dpkg -i $DEBS ; eend $?
1512 fi
1513 }
1514
1515 config_scripts(){
1516 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1517    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1518    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1519      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1520    fi
1521    if ! echo $SCRIPTS | grep -q '/'; then
1522      # backwards compatibility: if no path is given get scripts from scripts/
1523      SCRIPTS="scripts/$SCRIPTS"
1524    fi
1525    if [ -n "$SCRIPTS" ]; then
1526      SCRIPTS="${DCSDIR}/$SCRIPTS"
1527      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1528        einfo "Trying to execute ${SCRIPTS}"
1529        sh -c $SCRIPTS
1530        eend $?
1531      elif [ -d "$SCRIPTS" ]; then
1532        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1533        run-parts --regex '.*' $SCRIPTS
1534        eend $?
1535      else
1536        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1537        sh -c $SCRIPTS
1538        eend $?
1539      fi
1540    fi
1541 fi
1542 }
1543
1544 config_config(){
1545 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1546   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1547   if [ -z "$CONFIG" ]; then
1548     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1549   fi
1550   if [ -n "$CONFIG" ]; then
1551     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1552       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1553
1554       cp -a ${DCSDIR}/${CONFIG}/* /
1555     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1556       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1557
1558       cd /
1559       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1560     else
1561       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1562     fi
1563   fi
1564 fi
1565 }
1566 # }}}
1567
1568 # {{{ confing_umount_dcsdir
1569 config_umount_dcsdir(){
1570    # umount $DCSMP if it was mounted by finddcsdir
1571    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1572 }
1573 # }}}
1574
1575 # {{{ mypath
1576 config_mypath(){
1577 if checkbootparam 'mypath' ; then
1578    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1579    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1580    touch /etc/grml/my_path
1581    chmod 644 /etc/grml/my_path
1582    # make sure the directories exist:
1583    eindent
1584    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1585        if ! [ -d "$i" ] ; then
1586           einfo "Creating directory $i"
1587           mkdir -p "$i" ; eend $?
1588        fi
1589    done
1590    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1591    eoutdent
1592 fi
1593 }
1594 # }}}
1595
1596 # {{{ SW-RAID
1597 config_swraid(){
1598   [ -n "$INSTALLED" ] && return 0
1599
1600   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1601      checkbootparam 'raid=noautodetect' ; then
1602      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1603   else
1604     [ -e /proc/mdstat ] || modprobe md_mod
1605     if ! [ -x /sbin/mdadm ] ; then
1606        eerror "mdadm not available, can not execute it." ; eend 1
1607     else
1608
1609        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1610        # find out whether we have a valid configuration file already
1611        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1612           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1613           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1614           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1615         else
1616           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1617        fi
1618
1619        if ! checkbootparam 'swraid' ; then
1620           eindent
1621           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1622           eoutdent
1623        else
1624           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1625           eindent
1626            IFSOLD=${IFS:-}
1627            IFS='
1628 '
1629            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
1630                case $line in
1631                  *'No arrays found'*)
1632                    ewarn "$line" ; eend 0
1633                    ;;
1634                  *)
1635                    einfo "$line" ; eend 0
1636                    ;;
1637                esac
1638            done
1639            IFS=$IFSOLD
1640          eoutdent
1641
1642          if [ -r /proc/mdstat ] ; then
1643             eindent
1644             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1645             if [ -z "$MDSTAT" ] ; then
1646                ewarn "No active arrays found" ; eend 0
1647             else
1648                IFSOLD=${IFS:-}
1649                IFS='
1650 '
1651                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1652                    einfo "active arrays: $line" ; eend 0
1653                done
1654                IFS=$IFSOLD
1655             fi
1656             eoutdent
1657          fi # /proc/mdstat
1658        fi # bootoption swraid
1659
1660      fi # is /sbin/mdadm executable?
1661   fi # check for bootoptions
1662 }
1663 # }}}
1664
1665 # {{{ dmraid
1666 config_dmraid(){
1667   [ -n "$INSTALLED" ] && return 0
1668
1669   if checkbootparam 'nodmraid' ; then
1670     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1671     return 0
1672   fi
1673
1674   if ! [ -x /sbin/dmraid ] ; then
1675     eerror "dmraid not available, can not execute it." ; eend 1
1676     return
1677   fi
1678
1679   dmraid_wrapper() {
1680     # usage: dmraid_wrapper <dmraid_option>
1681     [ -n "$1" ] || return 1
1682
1683     IFSOLD=${IFS:-}
1684     IFS='
1685 '
1686     eindent
1687
1688     for line in $(dmraid $1 ; echo errcode:$?); do
1689       case $line in
1690         *'no block devices found'*)
1691           einfo "No block devices found" ; eend 0
1692           break
1693           ;;
1694         *'no raid disks'*)
1695           einfo "No active dmraid devices found" ; eend 0
1696           break
1697           ;;
1698         errcode:0)
1699           eend 0;
1700           ;;
1701         errcode:1)
1702           eend 1
1703           ;;
1704         *)
1705           einfo "$line"
1706           ;;
1707       esac
1708     done
1709
1710     eoutdent
1711     IFS=$IFSOLD
1712   }
1713
1714   if checkbootparam 'dmraid' ; then
1715     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1716     if [ "$ACTION" = "off" ] ; then
1717       # Deactivates all active software RAID sets:
1718       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1719       dmraid_wrapper -an
1720     else
1721       # Activate all software RAID sets discovered:
1722       einfo "Activating present dmraid sets (as requested via dmraid):"
1723       dmraid_wrapper -ay
1724     fi
1725
1726     return
1727   fi
1728
1729   # by default (no special bootoptions) discover all software RAID devices:
1730   einfo "Searching for any present dmraid sets:"
1731   dmraid_wrapper -r
1732 }
1733 # }}}
1734
1735 # {{{ LVM (Logical Volumes)
1736 config_lvm(){
1737   [ -n "$INSTALLED" ] && return 0
1738
1739   if checkbootparam 'nolvm' ; then
1740      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1741   else
1742     if ! [ -x /sbin/lvm ] ; then
1743        eerror "LVM not available, can not execute it." ; eend 1
1744     else
1745        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1746           einfo "You seem to have logical volumes (LVM) on your system."
1747           eindent
1748           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1749           eend 0
1750           if checkbootparam 'lvm' ; then
1751              einfo "Bootoption LVM found. Searching for logical volumes:"
1752              service_wrapper lvm2 start ; eend $?
1753           fi
1754           eoutdent
1755        fi
1756     fi # check for lvm binary
1757   fi # check for bootoption nolvm
1758 }
1759 # }}}
1760
1761 # {{{ debnet: setup network based on an existing one found on a partition
1762 config_debnet(){
1763 if checkbootparam 'debnet' ; then
1764  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1765  /usr/sbin/debnet
1766 fi
1767 }
1768 # }}}
1769
1770 # {{{ disable console blanking
1771 config_blanking(){
1772 if checkbootparam 'noblank' ; then
1773   einfo "Bootoption noblank found. Disabling monitor blanking."
1774   setterm -blank 0 ; eend $?
1775 fi
1776 }
1777 # }}}
1778
1779 # {{{ debootstrap: automatic installation
1780 config_debootstrap(){
1781
1782 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
1783
1784 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
1785
1786 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
1787    eindent
1788    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
1789    eoutdent
1790    exit 1
1791 fi
1792
1793 if checkbootparam 'target' ; then
1794   TARGET=''
1795   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
1796   # notice: the following checks whether the given partition is available, if not the skip
1797   # execution of grml-debootstrap as it might result in data loss...
1798   if ! [ -r "$TARGET" ] ; then
1799      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
1800   fi
1801 else
1802   eindent
1803   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
1804   eoutdent
1805   exit 1
1806 fi
1807
1808 if checkbootparam 'grub' ; then
1809   GRUB=''
1810   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
1811 fi
1812
1813 if checkbootparam 'groot' ; then
1814   GROOT=''
1815   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
1816 fi
1817
1818 if checkbootparam 'release' ; then
1819   RELEASE=''
1820   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
1821 fi
1822
1823 if checkbootparam 'mirror' ; then
1824   MIRROR=''
1825   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
1826 fi
1827
1828 if checkbootparam 'boot_append' ; then
1829   BOOT_APPEND=''
1830   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
1831 fi
1832
1833 if checkbootparam 'password' ; then
1834   PASSWORD=''
1835   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
1836 fi
1837
1838 # now check which options are available
1839 if [ -n "TARGET" ] ; then
1840    TARGETCMD="--target $TARGET"
1841 else
1842    TARGETCMD=''
1843    eindent
1844    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
1845    eoutdent
1846    exit 1
1847 fi
1848 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
1849 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
1850 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
1851 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
1852 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
1853 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
1854
1855 # and finally write script and execute it
1856 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
1857 #!/bin/sh
1858 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
1859 EOF
1860
1861 chmod 750  /usr/bin/grml-debootstrap_noninteractive
1862
1863 screen /usr/bin/grml-debootstrap_noninteractive
1864 einfo "Invoking a shell, just exit to continue booting..."
1865 /bin/zsh
1866
1867 fi # checkbootparam "BOOT_IMAGE=debian2hd
1868 }
1869 # }}}
1870
1871 # {{{ virtualbox shared folders
1872 config_virtualbox_shared_folders() {
1873 if $VIRTUALBOX ; then
1874   einfo "VirtualBox detected, trying to set up Shared Folders."
1875   if ! modinfo vboxsf &>/dev/null ; then
1876     ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
1877     eend 0
1878   elif ! [ -x /usr/sbin/VBoxService ] ; then
1879     ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
1880     eend 0
1881   else
1882     eindent
1883
1884       einfo "Loading vboxsf driver."
1885       lsmod | grep -q vboxsf || modprobe vboxsf
1886       eend $?
1887
1888       einfo "Adjusting /dev/vboxguest."
1889       chown root:vboxsf /dev/vboxguest
1890       chmod 660 /dev/vboxguest
1891       eend $?
1892
1893       config_userfstab
1894
1895       einfo "Adding $fstabuser to group vboxsf."
1896       adduser grml vboxsf &>/dev/null
1897       eend $?
1898
1899       einfo "Starting VBoxService."
1900       VBoxService >/dev/null
1901       eend $?
1902
1903       local vbautomation='automation'
1904       if checkbootparam 'vbautomation'; then
1905         vbautomation="$(getbootparam 'vbautomation' 2>>$DEBUG)"
1906       fi
1907
1908       if ! VBoxControl sharedfolder list | egrep -q "^[0-9]+ - ${vbautomation}$" ; then
1909         ewarn "No automount shared folder '$vbautomation' available"
1910         eend 0
1911       else
1912         einfo "Found automount shared folder '$vbautomation'"
1913         eend 0
1914
1915         local distri="$(getbootparam 'distri' 2>>$DEBUG)"
1916         [ -n "$distri" ] || distri='grml'
1917
1918         local vbox_auto_sf="/media/sf_${vbautomation}"
1919
1920         sleep 1 # ugly but necessary
1921
1922         counter=10
1923         eindent
1924         while ! [ -d "${vbox_auto_sf}" ] && [[ "$counter" != 0 ]]; do
1925           einfo "Waiting another second to retry access to ${vbox_auto_sf}"
1926           sleep 1
1927           counter=$(( counter-1 ))
1928           eend 0
1929         done
1930         eoutdent
1931
1932         if ! [ -d "${vbox_auto_sf}" ] ; then
1933           eerror "Giving up trying to access folder ${vbox_auto_sf} which doesn't seem to exist"
1934           eend 1
1935         else
1936           einfo "Found shared folders automation directory $vbox_auto_sf"
1937           eend 0
1938
1939           eindent
1940           if checkbootparam 'novbautomation' ; then
1941             einfo "Bootoption novbautomation found. Disabling automation script execution."
1942             eend 0
1943           else
1944             if ! [ -x "${vbox_auto_sf}/${distri}" ] ; then
1945               ewarn "Couldn't find an automation script named ${vbox_auto_sf}/${distri}"
1946               eend 1
1947             else
1948               einfo "Executing '${vbox_auto_sf}/${distri}' now:"
1949               "${vbox_auto_sf}/${distri}"
1950               eend $?
1951             fi
1952           fi
1953           eoutdent
1954         fi
1955       fi
1956
1957     eoutdent
1958   fi
1959 fi
1960 }
1961 # }}}
1962
1963 # {{{ Support customization
1964 config_distri(){
1965 if checkbootparam 'distri'; then
1966   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
1967   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
1968      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
1969      # make sure the desktop.jpg file is not a symlink, so copying does not file then
1970      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
1971      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
1972   fi
1973 fi
1974 }
1975 # }}}
1976
1977 ## END OF FILE #################################################################
1978 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=2