simple unit tests for {get,check}bootparam
[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:/usr/X11R6/bin"
11 DEBUG="/dev/null"
12 KERNEL="$(uname -r)"
13 umask 022
14
15 # old linuxrc version:
16 [ -d /cdrom ]      && export LIVECD_PATH=/cdrom
17 # new initramfs layout:
18 [ -d /live/image ] && export LIVECD_PATH=/live/image
19
20 # Ignore these signals in non-interactive mode: INT, TERM, SEGV
21 [ -z "$PS1" ] && trap "" 2 3 11
22
23 # zsh stuff
24 iszsh(){
25 if [ -n "$ZSH_VERSION" ] ; then
26   return 0
27 else
28   return 1
29 fi
30 }
31 # avoid 'no matches found: ...'
32 iszsh && setopt no_nomatch # || echo "Warning: not running under zsh!"
33 # }}}
34
35 # {{{ Read in boot parameters
36 if [ -z "$CMDLINE" ]; then
37   # if CMDLINE was set from the outside, we're debugging.
38   # otherwise, take CMDLINE from Kernel and config files.
39   CMDLINE="$(cat /proc/cmdline)"
40   [ -d /cdrom/bootparams/ ]      && CMDLINE="$CMDLINE $(cat /cdrom/bootparams/* | tr '\n' ' ')"
41   [ -d /live/image/bootparams/ ] && CMDLINE="$CMDLINE $(cat /live/image/bootparams/* | tr '\n' ' ')"
42 fi
43 # }}}
44
45 ### {{{ Utility Functions
46
47 # Get a bootoption's parameter: read boot command line and either
48 # echo last parameter's argument or return false.
49 getbootparam(){
50   local line
51   local ws
52   ws='   '
53   line=" $CMDLINE "
54   case "$line" in
55     *[${ws}]"$1="*)
56       result="${line##*[$ws]$1=}"
57       result="${result%%[$ws]*}"
58       echo "$result"
59       return 0 ;;
60     *) # no match?
61       return 1 ;;
62   esac
63 }
64
65 # Check boot commandline for specified option
66 checkbootparam(){
67   [ -n "$1" ] || ( echo "Error: missing argument to checkbootparam()" ; return 1 )
68   # make sure we match beginning and end of line as well
69   # but don't match 'vg' if we want to check for 'vga'
70   if echo "$CMDLINE" | grep -qw "$1" ; then
71      return 0
72   else
73      return 1
74   fi
75 }
76
77 # Check wheter a configuration variable (like $CONFIG_TOHD) is
78 # enabled or not
79 checkvalue(){
80   case "$1" in
81     [yY][eE][sS])     return 0 ;; # it's set to 'yes'
82     [tT][rR][uU][eE]) return 0 ;; # it's set to 'true'
83                    *) return 1 ;; # default
84   esac
85 }
86
87 # Are we using grml-small?
88 checkgrmlsmall(){
89   grep -q small /etc/grml_version 2>>$DEBUG && return 0 || return 1
90 }
91
92 # execute flite only if it's present
93 flitewrapper() {
94    [ -x /usr/bin/flite ] && flite -o play -t "$*"
95 }
96 ### }}}
97
98 # {{{ filesystems (proc, pts, sys) and fixes
99 mount_proc(){
100   [ -f /proc/version ] || mount -t proc /proc /proc 2>/dev/null
101 }
102
103 mount_pts(){
104   grep -q "/dev/pts" /proc/mounts || mount -t devpts /dev/pts /dev/pts 2>/dev/null
105 }
106
107 mount_sys(){
108   [ -d /sys/devices ] || mount -t sysfs /sys /sys 2>/dev/null
109 }
110 # }}}
111
112 # {{{ Check if we are running in live mode or from HD
113 INSTALLED=""
114 [ -e /etc/grml_cd ] || INSTALLED="yes"
115
116 # testcd
117 TESTCD=""
118 checkbootparam 'testcd' >>$DEBUG 2>&1 && TESTCD="yes"
119 # }}}
120
121 # {{{ source lsb-functions , color handling
122 if checkbootparam 'nocolor'; then
123   RC_NOCOLOR=yes
124   . /etc/grml/lsb-functions
125   einfo "Disabling colors in bootsequence as requested on commandline." ; eend 0
126 else
127   . /etc/grml/lsb-functions
128   . /etc/grml_colors
129 fi
130 # }}}
131
132 # {{{ debug
133 config_debug(){
134  checkbootparam 'debug'            && BOOTDEBUG="yes"
135  checkbootparam "BOOT_IMAGE=debug" && BOOTDEBUG="yes"
136
137  rundebugshell(){
138   if [ -n "$BOOTDEBUG" ]; then
139      einfo "Starting intermediate shell stage $stage as requested by \"debug\" option."
140      if [ grep -q "debug=noscreen" "$CMDLINE" ] ; then
141         einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
142         einfo "Just exit the shell to continue boot process..."
143         /bin/zsh
144      else
145         eindent
146         if [ -r /etc/grml/screenrc ] ; then
147            einfo "Starting GNU screen to be able to use a full featured shell environment."
148            einfo "Just exit the shells (and therefore screen) to continue boot process..."
149            /bin/zsh -c "screen -c /etc/grml/screenrc"
150         else
151            einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
152            einfo "Just exit the shell to continue boot process..."
153            /bin/zsh
154         fi
155         eoutdent
156      fi
157   fi
158  }
159 }
160 # }}}
161
162 # {{{ log
163 config_log(){
164 if checkbootparam 'log' || checkbootparam 'debug' ; then
165    export DEBUG="/tmp/grml.log.`date +%Y%m%d`"
166    touch $DEBUG
167    einfo "Bootparameter log found. Log files: ${DEBUG} and /var/log/boot"
168    eindent
169      einfo "Starting bootlogd." # known to be *very* unreliable :(
170      bootlogd -r -c 1>>$DEBUG 2>&1 ; eend $?
171    eoutdent
172 else
173    DEBUG="/dev/null"
174 fi
175 }
176 # }}}
177
178 # {{{ set firmware timeout via bootparam
179 config_fwtimeout(){
180  if checkbootparam 'fwtimeout' ; then
181    TIMEOUT="$(getbootparam 'fwtimeout' 2>>$DEBUG)"
182    einfo "Bootoption fwtimeout found. (Re)Loading firmware_class module."
183    rmmod firmware_class 1>>$DEBUG 2>&1
184    modprobe firmware_class ; eend $?
185  fi
186  if [ -z "$TIMEOUT" ] ; then
187    TIMEOUT="100" # linux kernel default: 10
188  fi
189  if [ -f /sys/class/firmware/timeout ] ; then
190    einfo "Setting timeout for firmware loading to ${TIMEOUT}."
191    echo 100 > /sys/class/firmware/timeout ; eend $?
192  fi
193 }
194 # }}}
195
196 ### {{{ language configuration / localization
197 config_language(){
198
199  einfo "Activating language settings:"
200  eindent
201
202  # people can specify $LANGUAGE and $CONSOLEFONT in a config file:
203  [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
204
205  grep -q ' lang=.*-utf8' /proc/cmdline && UTF8='yes' || UTF8=''
206
207  # check for bootoption which overrides config from /etc/grml/autoconfig:
208  BOOT_LANGUAGE="$(getbootparam 'lang' 2>>$DEBUG)"
209  [ -n "$BOOT_LANGUAGE" ] && LANGUAGE="$BOOT_LANGUAGE"
210
211  # set default to 'en' in live-cd mode if $LANGUAGE is not yet set:
212  if [ -z "$INSTALLED" ] ; then
213     [ -n "$LANGUAGE" ] || LANGUAGE='us'
214  fi
215
216  # if bootoption lang is used update /etc/default/locale, otherwise *not*!
217  if [ -n "$BOOT_LANGUAGE" -a -x /usr/sbin/grml-setlang ] ; then
218     if checkgrmlsmall ; then
219        /usr/sbin/grml-setlang "POSIX"
220     else
221        /usr/sbin/grml-setlang "$LANGUAGE"
222     fi
223  fi
224
225  # set console font
226  if [ -z "$CONSOLEFONT" ] ; then
227     if ! checkbootparam 'nodefaultfont' >>$DEBUG 2>&1 ; then
228        # [ -n "$UTF8" ] && CONSOLEFONT='LatArCyrHeb-16' || CONSOLEFONT='Lat15-Terminus16'
229        # if [ -r /usr/share/consolefonts/Lat15-Terminus16.psf.gz ] ; then
230        if [ -r /usr/share/consolefonts/Uni3-Terminus16.psf.gz ] ; then
231           CONSOLEFONT='Uni3-Terminus16'
232        else
233           ewarn "/usr/share/consolefonts/Uni3-Terminus16.psf.gz not available. Please upgrade package console-terminus." ; eend 1
234        fi
235     fi
236  fi
237
238  # export it now, so error messages get translated, too
239  if checkgrmlsmall ; then
240     export LANG='C' # grml-small does not provide any further locales
241  else
242     [ -r /etc/default/locale ] && . /etc/default/locale
243     export LANG LANGUAGE
244  fi
245
246  # configure keyboard layout, read in already set values first:
247  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
248
249  # now allow keyboard override by boot commandline for later use:
250  KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
251  [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
252  # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
253  [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
254  [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
255
256  # modify /etc/sysconfig/keyboard only in live-cd mode:
257  if [ -z "$INSTALLED" ] ; then
258
259    local LANGUAGE="$BOOT_LANGUAGE"
260    . /etc/grml/language-functions
261    # allow setting xkeyboard explicitly different than console keyboard
262    KXKEYBOARD="$(getbootparam 'xkeyboard' 2>>$DEBUG)"
263    if [ -n "$KXKEYBOARD" ]; then
264       XKEYBOARD="$KXKEYBOARD"
265       KDEKEYBOARD="$KXKEYBOARD"
266    elif [ -n "$KKEYBOARD" ]; then
267       XKEYBOARD="$KKEYBOARD"
268       KDEKEYBOARD="$KKEYBOARD"
269    fi
270
271    # duplicate of previous code to make sure /etc/grml/language-functions
272    # does not overwrite our values....
273    # now allow keyboard override by boot commandline for later use:
274    KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
275    [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
276    # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
277    [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
278    [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
279
280    # write keyboard related variables to file for later use
281    [ -d /etc/sysconfig ] || mkdir /etc/sysconfig
282    if ! [ -e /etc/sysconfig/keyboard ] ; then
283       echo "KEYTABLE=\"$KEYTABLE\""          > /etc/sysconfig/keyboard
284       echo "XKEYBOARD=\"$XKEYBOARD\""       >> /etc/sysconfig/keyboard
285       echo "KDEKEYBOARD=\"$KDEKEYBOARD\""   >> /etc/sysconfig/keyboard
286       echo "KDEKEYBOARDS=\"$KDEKEYBOARDS\"" >> /etc/sysconfig/keyboard
287    fi
288  fi
289
290  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
291
292  # activate unicode console if running within utf8 environment
293  if [ -r /etc/default/locale ] ; then
294     if grep -q "LANG=.*UTF" /etc/default/locale ; then
295        einfo "Setting up unicode environment."
296        unicode_start 2>>$DEBUG ; eend $?
297     fi
298  fi
299
300  # Set default keyboard before interactive setup
301  if [ -n "$KEYTABLE" ] ; then
302     einfo "Running loadkeys for ${WHITE}${KEYTABLE}${NORMAL} in background"
303     loadkeys -q $KEYTABLE &
304     eend $?
305  fi
306
307  # we have to set up all consoles, therefore loop it over all ttys:
308  NUM_CONSOLES=$(fgconsole --next-available)
309  NUM_CONSOLES=$(expr ${NUM_CONSOLES} - 1)
310  [ ${NUM_CONSOLES} -eq 1 ] && NUM_CONSOLES=6
311  CUR_CONSOLE=$(fgconsole)
312
313  if [ -n "$CHARMAP" ] ; then
314     einfo "Running consolechars for ${CHARMAP}"
315     for vc in `seq 0 ${NUM_CONSOLES}`  ; do
316         consolechars --tty=/dev/tty${vc} -m ${CHARMAP} ; RC=$?
317     done
318     [ -n "$CUR_CONSOLE" ] && chvt $CUR_CONSOLE
319     eend $RC
320  fi
321
322  if checkbootparam 'noconsolefont' ; then
323     ewarn "Skipping setting console font as requested on boot commandline." ; eend 0
324  else
325     if [ -n "$CONSOLEFONT" ] ; then
326        einfo "Running consolechars using ${CONSOLEFONT}"
327        for vc in `seq 0 ${NUM_CONSOLES}`  ; do
328            consolechars --tty=/dev/tty${vc} -f $CONSOLEFONT ; RC=$?
329        done
330        [ -n "$CUR_CONSOLE" ] && chvt $CUR_CONSOLE
331        eend $?
332     fi
333  fi
334
335  eoutdent
336 }
337 # }}}
338
339 # {{{ Set hostname
340 config_hostname(){
341  if checkbootparam 'hostname' ; then
342   HOSTNAME="$(getbootparam 'hostname' 2>>$DEBUG)"
343   einfo "Setting hostname to $HOSTNAME as requested."
344   sed -i "s/^127.0.0.1.*localhost/127.0.0.1 $HOSTNAME localhost/" /etc/hosts
345   hostname $HOSTNAME ; eend $?
346  else
347   hostname --file /etc/hostname
348  fi
349 }
350 # }}}
351
352 # fstabuser (needed when running from harddisk with username != grml {{{
353 config_userfstab(){
354   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
355   if [ -n "$CONFIG_FSTAB_USER" ] ; then
356      fstabuser="$CONFIG_FSTAB_USER"
357   else
358      fstabuser=$(getent passwd 1000 | cut -d: -f1)
359   fi
360   # if not yet set fall back to default 'grml' user
361   [ -n "$fstabuser" ] || fstabuser='grml'
362 }
363 # }}}
364
365 # {{{ Set clock (Local time is more often used than GMT, so it is default)
366 config_time(){
367  # don't touch the files if running from harddisk:
368  if [ -z "$INSTALLED" ]; then
369     # The default hardware clock timezone is stated as representing local time.
370     UTC="--localtime"
371     grep -q "^UTC=" /etc/default/rcS || echo "UTC=no" >> /etc/default/rcS
372     checkbootparam 'utc'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
373     checkbootparam 'gmt'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
374     checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=no|"  /etc/default/rcS
375     grep -q -i "^UTC=yes" /etc/default/rcS && UTC="-u"
376     # hwclock uses the TZ variable
377     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
378     [ -z "$KTZ" ] && [ -r /etc/timezone ] && KTZ=$(cat /etc/timezone)
379     if [ ! -f "/usr/share/zoneinfo/$KTZ" ] ; then
380        ewarn "Warning: unknown timezone $KTZ" ; eend 1
381        KTZ="Europe/Vienna"
382        ewarn "Falling back to timezone $KTZ" ; eend 0
383     fi
384
385     if ! [ -r /dev/rtc ] ; then
386       ewarn "Warning: realtime clock not available, trying to execute hwclock anyway." ; eend 0
387     fi
388
389     ERROR=$(TZ="$KTZ" hwclock $UTC -s 2>&1 | head -1) ; RC=$?
390     if [ -n "$ERROR" ] ; then
391        eindent
392        ERROR=$(TZ="$KTZ" hwclock $UTC -s --directisa 2>&1 | head -1)
393        if [ -n "$ERROR" ] ; then
394           eerror "Problem running hwclock: $ERROR" ; eend 1
395        fi
396        eoutdent
397     fi
398
399  fi
400 }
401 # }}}
402
403 # {{{ print kernel info
404 config_kernel(){
405   vmware-detect &>/dev/null && VMWARE="inside ${WHITE}VMware/Qemu${NORMAL}"
406   [ -d /proc/xen ] && VMWARE='' # vmware-detect returns '0' when running with a Xen-enabled kernel
407   einfo "Running Linux Kernel $KERNEL $VMWARE" ; eend 0
408   if [ -r /proc/cpuinfo ] ; then
409      if egrep -q '^flags.*(vmx|svm)' /proc/cpuinfo ; then
410        eindent
411        einfo 'CPU(s) featuring virtualization technology detected' ; eend 0
412        eoutdent
413      fi
414   fi
415   if [ -d /proc/xen ] ; then
416      eindent
417      einfo 'Running kernel featuring support for Xen detected' ; eend 0
418      eoutdent
419   fi
420 }
421 # }}}
422
423 # {{{ vmware specific stuff
424 config_vmware(){
425 if checkbootparam 'novmware' ; then
426    ewarn "Skipping running vmware specific stuff as requested on boot commandline." ; eend 0
427 else
428    if [ -z "$INSTALLED" ] ; then
429       if vmware-detect || checkbootparam "BOOT_IMAGE=vmware" ; then
430          if ! checkbootparam 'qemu' ; then
431             if [ -r /etc/X11/xorg.conf.vmware ] ; then
432                einfo "VMware: Copying /etc/X11/xorg.conf.vmware to /etc/X11/xorg.conf"
433                cp /etc/X11/xorg.conf.vmware /etc/X11/xorg.conf ; eend $?
434             fi
435          fi
436       elif [ -r /proc/acpi/battery/BAT0/info -a -r /etc/X11/xorg.conf.virtualbox ] ; then
437          if grep -q 'OEM info:                innotek' /proc/acpi/battery/BAT0/info ; then
438             einfo 'Virtual Box: Copying /etc/X11/xorg.conf.virtualbox to /etc/X11/xorg.conf'
439             cp /etc/X11/xorg.conf.virtualbox /etc/X11/xorg.conf ; eend $?
440          fi
441       fi
442    fi
443 fi
444 }
445 # }}}
446
447 # {{{ qemu specific stuff
448 config_qemu(){
449 if checkbootparam 'qemu' ; then
450    if [ -r /etc/X11/xorg.conf.example ] ; then
451       einfo "Qemu: Copying /etc/X11/xorg.conf.example to /etc/X11/xorg.conf"
452       cp /etc/X11/xorg.conf.example /etc/X11/xorg.conf ; eend $?
453    fi
454 fi
455 }
456 # }}}
457
458 # {{{ ld.so.cache + depmod
459 config_ld_mod(){
460 if [ -n "$INSTALLED" ]; then
461  if ! [ -r /etc/grml.first.boot ] ; then
462   einfo "Running from HD for the first time, regenerate ld.so.cache and modules.dep:"
463   eindent
464 # Regenerate ld.so.cache and module dependencies on HD
465     einfo "Running ldconfig" ; ldconfig  ; eend $?
466     einfo "Running depmod"   ; depmod -a ; eend $?
467     touch /etc/grml.first.boot
468     eend 0
469   eoutdent
470  fi
471 fi
472 }
473 # }}}
474
475 # {{{ timezone
476 config_timezone(){
477  # don't touch the files if running from harddisk:
478  if [ -z "$INSTALLED" ]; then
479     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
480     if [ -n "$KTZ" ] ; then
481        if [ ! -f "/usr/share/zoneinfo/$KTZ" ]
482        then
483           ewarn "Warning: unknown timezone $KTZ"; eend 0
484        else
485           einfo "Setting timezone."
486           # update debconf
487           area=$(echo $KTZ | cut -d '/' -f1)
488           zone=$(echo $KTZ | cut -d '/' -f2)
489           echo "tzdata tzdata/Areas       select $area" | debconf-set-selections
490           echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections
491           # update files
492           echo $KTZ > /etc/timezone
493           rm -f /etc/localtime
494           cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $?
495        fi
496     fi
497  fi
498 }
499 # }}}
500
501 # small computer / nearly no ram {{{
502 config_small(){
503
504 RAM=$(/usr/bin/gawk '/MemTotal/{print $2}' /proc/meminfo)
505 # MEM=$(/usr/bin/gawk 'BEGIN{m=0};/MemFree|Cached|SwapFree/{m+=$2};END{print m}' /proc/meminfo)
506 eindent
507
508 if checkbootparam 'small'; then
509   einfo "Information: ${RAM} kB of RAM available." ; eend 0
510   einfo "Bootoption small detected. Activating small system."
511   if [ -r /etc/inittab.small ] ; then
512     mv /etc/inittab /etc/inittab.normal
513     mv /etc/inittab.small /etc/inittab
514   else
515     sed -i 's/^9/#&/' /etc/inittab
516     sed -i 's/^10/#&/' /etc/inittab
517     sed -i 's/^11/#&/' /etc/inittab
518     sed -i 's/^12/#&/' /etc/inittab
519   fi
520   /sbin/telinit q ; eend $?
521 else
522   if checkgrmlsmall ; then
523     if [[ $RAM -lt 25000 ]] ; then
524       ewarn "Information: ${RAM} kB of RAM available." ; eend 1
525       ewarn "At least 32MB of RAM should be available for grml-small." ; eend 1
526       ewarn "Use the bootoption small to save some more MB of memory usage." ; eend 0
527       ewarn "Dropping you into a rescue shell. To continue booting exit the shell." ; eend 0
528       /bin/zsh --login
529     else
530       einfo "Information: ${RAM} kB of RAM available." ; eend 0
531     fi
532   else
533     if [[ $RAM -lt 58000 ]] ; then
534       ewarn "Information: ${RAM} kB of RAM available." ; eend 1
535       ewarn "At least 64MB of RAM should be available for grml." ; eend 1
536       ewarn "Use the bootoption small to save some more MB of memory usage." ; eend 0
537       ewarn "Dropping you into a rescue shell. To continue booting exit the shell." ; eend 0
538       /bin/zsh --login
539     else
540       einfo "Information: ${RAM} kB of RAM available." ; eend 0
541     fi
542   fi
543 fi
544 eoutdent
545 }
546 # }}}
547
548 # skip startup of w3m {{{
549 config_fast(){
550 if checkbootparam 'fast'; then
551   ewarn "Bootoption fast detected. Skipping startup of grml-quickconfig."
552     sed -i 's#^1:.*#1:12345:respawn:/usr/bin/openvt -f -c 1 -w -- /bin/zsh#' /etc/inittab
553   /sbin/telinit q ; eend $?
554 fi
555 }
556 # }}}
557
558 # activate serial console {{{
559 config_console(){
560 if checkbootparam 'console'; then
561   einfo "Bootoption (for serial) console detected."
562   eindent
563     if [ -r /etc/mgetty/mgetty.config ] ; then
564        MODE=$(getbootparam 'console' | awk -F, '{print $2}')
565        MODE=${MODE%%n*}
566        [ -n "$MODE" ] || MODE=9600 # default mode
567        einfo "Setting speed in /etc/mgetty/mgetty.config to $MODE bps"
568        sed -i "s/speed [0-9]*/speed $MODE/" /etc/mgetty/mgetty.config ; eend $?
569     fi
570
571     einfo "Activating mgetty."
572     sed -i 's/^#T0/T0/' /etc/inittab
573     sed -i 's/^#T1/T1/' /etc/inittab
574     /sbin/telinit q ; eend $?
575   eoutdent
576 fi
577 }
578 # }}}
579
580 # For burning on IDE-CD-Roms, k3b (and others) check for special permissions {{{
581 config_cdrom_perm(){
582 CDROMS=""
583 for DEVICE in /proc/ide/hd?; do
584  [ "$(cat $DEVICE/media 2>/dev/null)" = "cdrom" ] && CDROMS="$CDROMS /dev/${DEVICE##*/}"
585 done
586 [ -n "$CDROMS" ] && { chown root.cdrom $CDROMS; chmod 666 $CDROMS; } 2>/dev/null
587 }
588 # }}}
589
590 # {{{ Bring up loopback interface now
591 config_local_net(){
592  if [ -z "$INSTALLED" ] ; then
593     if grep -q 'iface lo inet loopback' /etc/network/interfaces 2>/dev/null ; then
594        grep -q lo=lo /etc/network/run/ifstate 2>/dev/null || ifup lo
595     else
596        ifconfig lo up
597     fi
598  fi
599 }
600 # }}}
601
602 # firewire devices {{{
603 # the raw1394 driver does not yet export info into SYSFS,
604 # so let's create raw1394 device manually
605 # http://www.michael-prokop.at/blog/index.php?p=352
606 config_firewire_dev(){
607 if checkbootparam 'nofirewiredev' ; then
608   ewarn "Skipping creating some firewire devices as requested on boot commandline." ; eend 0
609 else
610 #if [ "${KERNEL%-*}" == "2.6.11" ] ; then
611   einfo "Creating some firewire devices (fix kernel 2.6-bug)."
612 #  cd /dev && MAKEDEV video1394 raw1394
613   [ -r /dev/raw1394 ]   || mknod /dev/raw1394 c 171 0
614   [ -r /dev/video1394 ] || mknod -m 666 /dev/video1394 c 171 16
615 # mknod -m 666 /dev/dv1394 c 171 32 # for NTSC
616   [ -r /dev/dv1394 ]    || mknod -m 666 /dev/dv1394 c 171 34 # for PAL
617   chown -R root:video /dev/raw1394 /dev/video1394 /dev/dv1394
618   chmod -R 664 /dev/raw1394 /dev/video1394 /dev/dv1394 ; eend $?
619 fi
620 #fi
621 }
622 # }}}
623
624 # {{{ copy passwd-lockfile to ramdisk (fix unionfs-behaviour)
625 # otherwise we will get: passwd: Authentication token lock busy
626 config_fix_passwd(){
627  if [ -z "$INSTALLED" ] ; then
628   touch /etc/.pwd.lock
629  fi
630 }
631 # }}}
632
633 # {{{ CD Checker
634 config_testcd(){
635 if [ -n "$TESTCD" ]; then
636    einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
637    einfo "Reading files and checking against GRML/md5sums, this may take a while..."
638    echo -n "${RED}"
639
640    if [ -n "${LIVECD_PATH}"/GRML ] ; then
641       ( cd "${LIVECD_PATH}"/GRML ; rm -f /tmp/md5sum.log ; md5sum -c md5sums 2>&1 | tee /tmp/md5sum.log ; RC=$? )
642    else
643       echo "${RED} *** Error: Could not find md5sum file.                           ***"
644    fi
645
646    if [ "$RC" = "0" ]; then
647       einfo "Everything looks OK" ; eend 0
648    else
649       eerror 'Checksum failed for theses files:' ; eend 1
650       egrep -v '(^md5sum:|OK$)' /tmp/md5sum.log
651       eerror 'Data on the grml medium is possibly incomplete/damaged or...'
652       eerror '... RAM of your computer is broken.' ; eend 1
653       einfon "Hit return to continue, or press the reset button to quit."
654      read a
655    fi
656
657    eend 0
658 fi
659 }
660 # }}}
661
662 # {{{ hardware detection via discover
663 config_discover(){
664 if checkbootparam 'nodisc' ; then
665   ewarn "Skipping hardware detection via discover as requested on boot commandline." ; eend 0
666 else
667  if [ -x /sbin/discover ] ; then
668   einfo "Discovering hardware. Trying to load the following modules in background:"
669    eindent
670    einfo "$(discover --data-path=linux/module/name --data-path=linux/modules/options --format="%s %s" --data-version=`uname -r` --enable-bus all | sort -u | xargs echo)"
671    eoutdent
672   /sbin/discover-modprobe -v 1>>$DEBUG 2>&1 &
673   eend 0
674  else
675   eerror "Application discover not available. Information: udev should handle hardware recognition." ; eend 0
676  fi
677 fi
678 }
679 # }}}
680
681 # {{{ hardware detection via hwinfo
682 config_hwinfo(){
683 if checkbootparam 'hwinfo' >>$DEBUG 2>&1; then
684   einfo "Discovering hardware via hwinfo:"
685   MODULES=$(su grml hwinfo | grep "Cmd: \"modprobe" | awk '{print $5}' | sed 's/"//')
686   echo -n "  Loading modules: "
687   for i in `echo $MODULES` ; do echo -n $i && modprobe $i ; done
688   eend 0
689 fi
690 }
691 # }}}
692
693 # {{{ disable hotplug agents on request
694 config_hotplug_agent(){
695 if checkbootparam 'noagent' ; then
696   AGENT="$(getbootparam 'noagent' 2>>$DEBUG)"
697   AGENTLIST=$(echo "$AGENT" | sed 's/,/\\n/g')
698   AGENTNL=$(echo "$AGENT" | sed 's/,/ /g')
699   einfo "Disabling hotplug-agent(s) $AGENTNL"
700   for agent in $(echo -e $AGENTLIST) ; do
701     mv /etc/hotplug/${agent}.rc /etc/hotplug/${agent}.norc
702   done
703   [ "$?" == "0" ] ; eend $?
704 fi
705 }
706 # }}}
707
708 # {{{ blacklist of hotplug-modules
709 config_hotplug_blacklist(){
710 if checkbootparam 'black' ; then
711   BLACK="$(getbootparam 'black' 2>>$DEBUG)"
712   BLACKLIST=$(echo "$BLACK" | sed 's/,/\\n/g')
713   BLACKNL=$(echo "$BLACK" | sed 's/,/ /g')
714   einfo "Blacklisting $BLACKNL via /etc/hotplug/blacklist.d/hotplug-light"
715   echo -e "$BLACKLIST" >> /etc/hotplug/blacklist.d/hotplug-light
716   echo -e "$BLACKLIST" >> /etc/hotplug/blacklist
717   eend 0
718 fi
719 }
720 # }}}
721
722 # {{{ run hotplug
723 config_hotplug(){
724 if checkbootparam 'nohotplug' ; then
725   ewarn "Skipping running hotplug as requested on boot commandline." ; eend 0
726 else
727   if [ -r /etc/init.d/hotplug ] ; then
728     einfo "Starting hotplug system in background."
729     /etc/init.d/hotplug start 1>>$DEBUG 2>>$DEBUG &
730     eend 0
731   elif [ -r /etc/init.d/hotplug-light ] ; then
732     einfo "Starting hotplug-light system in background."
733     /etc/init.d/hotplug-light start 1>>$DEBUG 2>>$DEBUG &
734     eend 0
735   else
736     ewarn "No hotplug system found. Should be handled by udev. Skipping execution." ; eend 0
737   fi
738 fi
739 }
740 # }}}
741
742 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
743 config_blacklist(){
744 if checkbootparam 'blacklist' ; then
745  if [ -z "$INSTALLED" ]; then
746   einfo "Bootoption blacklist found."
747   BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
748   BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
749   if [ -n "$BLACK" ] ; then
750     for module in $(echo ${BLACK//,/ }) ; do
751         einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
752         echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
753         echo "blacklist $module"     >> "$BLACKLIST_FILE"
754         echo "alias     $module off" >> "$BLACKLIST_FILE"
755         echo "# end   entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
756     done
757   else
758    eerror "No given module for blacklist found. Blacklisting will not work therefore."
759   fi
760  else
761   ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
762   eindent
763    einfo "Please blacklist the module(s) manually using the 'blacklist' script."
764   eoutdent
765  fi
766 fi
767 }
768 # }}}
769
770 # {{{ ACPI
771 config_acpi_apm(){
772 if [ -d /proc/acpi ]; then
773   if checkbootparam 'noacpi'; then
774     ewarn "Skipping ACPI Bios detection as requested via noacpi on boot commandline." ; eend 0
775   elif checkbootparam 'nogrmlacpi' ; then
776     ewarn "Skipping ACPI Bios detection as requested via nogrmlacpi on boot commandline." ; eend 0
777   else
778     einfo "ACPI Bios found, activating modules (disable via bootoption noacpi / nogrmlacpi): "
779     eindent
780     found=""
781     for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
782       basename="${a##*/}"
783       basename="${basename%%.*}"
784       case "$basename" in *_acpi)
785        egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
786       esac
787       modprobe $basename >>$DEBUG 2>&1 && found="yes"
788       local BASE="$BASE $basename"
789     done
790     if [ -n "$found" ] ; then
791       einfo "$BASE"  ; eend 0
792     else
793       ewarn "(none)" ; eend 1
794     fi
795     if ! ps x | grep -q /usr/sbin/acpid ; then
796       if ! [ -r /var/run/dbus/pid ] ; then
797         einfo "Starting acpi daemon."
798         /etc/init.d/acpid start 1>>$DEBUG 2>&1 ; eend $?
799       else
800         eerror "acpid error: it seems you are running d-bus/hal, but acpid needs to be started before d-bus."
801         eerror "Solution: please activate acpid via /etc/runlevel.conf"
802         eend 1
803       fi
804     else
805       ewarn "acpi daemon already running."
806       eend 0
807     fi
808     eoutdent
809   fi
810 else
811 # APM
812   if checkbootparam 'noapm'; then
813     ewarn "Skipping APM Bios detection as requested on boot commandline." ; eend 0
814   else
815     modprobe apm power_off=1 >>$DEBUG 2>&1
816     if [ "$?" = "0" ] ; then
817        if [ -x /etc/init.d/apmd ] ;then
818           einfo "APM Bios found, enabling power management functions."
819           /etc/init.d/apmd start ; eend $?
820        fi
821     else
822       eerror "Loading apm module failed." ; eend 1
823     fi
824   fi
825 fi
826 }
827 # }}}
828
829 # {{{ PCMCIA Check/Setup
830 # This needs to be done before other modules are being loaded (by hwsetup)
831 config_pcmcia(){
832 if checkbootparam 'nopcmcia'; then
833   ewarn "Skipping PCMCIA detection as requested on boot commandline." ; eend 0
834 else
835   if /usr/sbin/laptop-detect ; then
836     einfo "Detected Laptop - checking for PCMCIA." && eend 0
837     modprobe pcmcia_core >>$DEBUG 2>&1
838     # Try Cardbus or normal PCMCIA socket drivers
839     modprobe yenta_socket >>$DEBUG 2>&1 || modprobe i82365 >>$DEBUG 2>&1 || modprobe pd6729 >>$DEBUG 2>&1 || modprobe tcic >>$DEBUG 2>&1
840     if [ "$?" = "0" ]; then
841       modprobe ds >>$DEBUG 2>&1
842       if [ -d /proc/bus/pccard ] ; then
843        if [ -x /sbin/cardmgr ] ; then
844         einfo "PCMCIA found, starting cardmgr."
845         cardmgr >>$DEBUG 2>&1 && sleep 6 && eend 0
846        else
847         eerror "No cardmgr found. Make sure package pcmciautils is installed, it should handle it instead." ; eend 1
848        fi
849       fi
850     fi
851   fi
852 fi
853 }
854 # }}}
855
856 # {{{ run software synthesizer via speakup
857 config_swspeak(){
858    if checkbootparam 'swspeak' ; then
859       einfo "Bootoption swspeak found."
860
861       if [ ! -d /proc/speakup/ ] && ! grep -q speakup_soft /proc/modules ; then
862          ewarn "Kernel does not support software speakup - trying to load kernel module:" ; eend 0
863          eindent
864          einfo "Loading speakup_soft"
865          if modprobe speakup_soft ; then
866             eend 0
867          else
868             flitewrapper "Fatal error setting up software speakup"
869             eend 1
870             return 1
871          fi
872          eoutdent
873       fi
874
875       if [ -d /proc/speakup/ ] || grep -q speakup_soft /proc/modules ; then
876          einfo "Kernel supports speakup." ; eend 0
877          eindent
878             einfo "Just run swspeak if you want to use software synthesizer via speakup."
879             flitewrapper "Finished activating software speakup. Just run swspeak when booting finished."
880          eoutdent
881       else
882          eerror "Kernel does not seem to support speakup. Skipping swspeak." ; eend 1
883          flitewrapper "Kernel does not seem to support speakup. Sorry."
884       fi
885    fi
886 }
887 # }}}
888
889 # {{{ support hardware synthesizer via speakup
890 config_hwspeak(){
891    if checkbootparam 'speakup.synth' ; then
892       einfo "Bootoption speakup.synth found."
893       eindent
894
895       module="$(getbootparam 'speakup.synth' 2>>$DEBUG)"
896       if [ -z "$module" ] ; then
897          eerror "Sorry, no speakup module specified for bootoption speakup.synth."
898          flitewrapper "Sorry, no speakup module specified for bootoption speakup.synth."
899       else
900          einfo "Trying to load $module"
901          modprobe "speakup_${module}"
902          eend $?
903       fi
904
905       if [ -d /proc/speakup/ ] || grep -q speakup /proc/modules ; then
906          einfo "Kernel should support speakup now." ; eend 0
907          flitewrapper "Kernel should support speakup now."
908       else
909          eerror "Kernel or hardware do not seem to support speakup. Skipping hwspeak." ; eend 1
910          flitewrapper "Kernel or hardware do not seem to support speakup. Sorry."
911       fi
912
913       eoutdent
914
915    # hwspeak:
916    elif checkbootparam 'hwspeak' ; then
917       einfo "Bootoption hwspeak found."
918
919       if [ ! -d /proc/speakup/ ] && ! grep -q speakup /proc/modules ; then
920          ewarn "Kernel does not support hardware speakup - trying to load kernel modules:" ; eend 0
921          eindent
922          if ! [ -d "/lib/modules/${KERNEL}/extra/speakup/" ] ; then
923             eerror "Kernel does not provide speakup modules, sorry." ; eend 1
924          else
925            for module in $(find "/lib/modules/${KERNEL}/extra/speakup/" -name \*.ko | \
926                            sed 's#.*speakup/##g ; s#.ko$##g' | \
927                            grep -ve speakup_soft -ve speakup_dummy | sort -u) ; do
928               einfo "Trying to load $module"
929               modprobe $module
930               eend $?
931            done
932          fi
933          eoutdent
934       fi
935
936       if [ -d /proc/speakup/ ] || grep -q speakup /proc/modules ; then
937          einfo "Kernel should support speakup now." ; eend 0
938          flitewrapper "Kernel should support speakup now."
939       else
940          eerror "Kernel or hardware do not seem to support speakup. Skipping hwspeak." ; eend 1
941          flitewrapper "Kernel or hardware do not seem to support speakup. Sorry."
942       fi
943    fi
944 }
945 # }}}
946
947 # {{{ Check for blind option or brltty
948 config_blind(){
949 BLIND=""
950 checkbootparam 'blind' && BLIND="yes"
951 BRLTTY="$(getbootparam 'brltty' 2>>$DEBUG)"
952
953 if [ -n "$BLIND" -o -n "$BRLTTY" ]; then
954   if [ -x /sbin/brltty ]; then
955     # Blind option detected, start brltty now.
956     # modprobe serial_core parport_serial generic_serial && echo "done"
957     CMD=brltty
958     BRLTYPE=""
959     BRLDEV=""
960     BRLTEXT=""
961     if [ -n "$BRLTTY" ]; then
962       # Extra options
963       BRLTYPE="${BRLTTY%%,*}"
964       R="${BRLTTY#*,}"
965       if [ -n "$R" -a "$R" != "$BRLTTY" ]; then
966         BRLTTY="$R"
967         BRLDEV="${BRLTTY%%,*}"
968         R="${BRLTTY#*,}"
969         if [ -n "$R" -a "$R" != "$BRLTTY" ]; then
970           BRLTTY="$R"
971           BRLTEXT="${BRLTTY%%,*}"
972           R="${BRLTTY#*,}"
973         fi
974       fi
975     fi
976     [ -n "$BRLTYPE" ] && CMD="$CMD -b $BRLTYPE"
977     [ -n "$BRLDEV"  ] && CMD="$CMD -d $BRLDEV"
978     [ -n "$BRLTEXT" ] && CMD="$CMD -t $BRLTEXT"
979     einfo "Starting braille-display manager."
980 #    ( exec $CMD & )
981     ( sh -c "$CMD" & )
982     sleep 2 && BLINDSOUND="yes"
983     eend 0
984   fi
985 fi
986 }
987 # }}}
988
989 # {{{ Interactive configuration
990 config_interactive(){
991   ewarn "config_interactive is deprecated nowadays."
992   ewarn "Please set CONFIG_INTERACTIVE='no' in /etc/grml/autoconfig" ; eend 0
993 }
994 # }}}
995
996 # {{{ AGP
997 config_agp(){
998 if checkbootparam 'forceagp' ; then
999 # Probe for AGP. Hope this can fail safely
1000   grep -q "AGP" "/proc/pci" 2>>$DEBUG && { modprobe agpgart || modprobe agpgart agp_try_unsupported=1; } >>$DEBUG 2>&1 && einfo "AGP bridge detected." ; eend 0
1001 fi
1002 }
1003 # }}}
1004
1005 # {{{ automount(er)
1006 config_automounter(){
1007 if checkbootparam 'automounter' ; then
1008   RUNLEVEL="$(runlevel)"
1009   AUTOMOUNTER=""
1010   [ -x /etc/init.d/autofs ] && [ "$RUNLEVEL" != "N 1" ] && [ "$RUNLEVEL" != "N S" ] && AUTOMOUNTER="yes"
1011
1012 addautomount(){
1013 # /dev/ice  options
1014   d="${1##*/}"
1015   if [ -n "$AUTOMOUNTER" ]; then
1016     [ -d "/mnt/$d" -a ! -L "/mnt/$d" ] && rmdir /mnt/$d
1017     [ -d "/mnt/auto/$d" ] || mkdir -p "/mnt/auto/$d"
1018     [ -L "/mnt/$d" ]      || ln -s "/mnt/auto/$d" "/mnt/$d"
1019     anew="$d        -fstype=auto,$2 :$i"
1020     grep -q "$anew" "/etc/auto.mnt" || echo "$anew" >> /etc/auto.mnt
1021     AUTOMOUNTS="$AUTOMOUNTS $d"
1022     new="$1 /mnt/auto/$d  auto   users,noauto,exec,$2 0 0"
1023   else
1024     [ -d /mnt/$d ] && mkdir -p /mnt/$d
1025     new="$1 /mnt/$d  auto   users,noauto,exec,$2 0 0"
1026   fi
1027   grep -q "$new" "/etc/fstab" || echo "$new" >> /etc/fstab
1028 }
1029
1030   AUTOMOUNTS="floppy cdrom"
1031 # Add new devices to /etc/fstab and /etc/auto.mnt
1032   for i in /dev/cdrom?*; do
1033     if [ -L $i ]; then
1034       addautomount "$i" "ro"
1035     fi
1036   done
1037 fi
1038
1039 if [ -n "$AUTOMOUNTER" ]; then
1040 # Check for floppy dir, reinstall with automounter
1041   [ -d /mnt/floppy -a ! -L /mnt/floppy ] && rmdir /mnt/floppy
1042   [ -d /mnt/auto/floppy ] || mkdir -p /mnt/auto/floppy
1043   [ -L /mnt/floppy ] || ln -s /mnt/auto/floppy /mnt/floppy
1044   [ -d /mnt/cdrom -a ! -L /mnt/cdrom ] && rmdir /mnt/cdrom
1045   [ -d /mnt/auto/cdrom ] || mkdir -p /mnt/auto/cdrom
1046   [ -L /mnt/cdrom ] || ln -s /mnt/auto/cdrom /mnt/cdrom
1047   rm -f /etc/fstab.new
1048 # Replace paths from bootfloppy
1049   sed 's|/mnt/cdrom|/mnt/auto/cdrom|g;s|/mnt/floppy|/mnt/auto/floppy|g' /etc/fstab > /etc/fstab.new
1050   mv -f /etc/fstab.new /etc/fstab
1051 # Start automounter now
1052   einfo "Starting automounter for ${AUTOMOUNTS}."
1053   /etc/init.d/autofs start >>$DEBUG ; eend $?
1054 fi
1055 }
1056 # }}}
1057
1058 # {{{ Collect partitions from /proc/partitions first for enabling DMA
1059 check_partitions(){
1060 partitions=""
1061 IDEDISKS=""
1062 while read major minor blocks partition relax; do
1063   partition="${partition##*/}"
1064   [ -z "$partition" -o ! -e "/dev/$partition" ] && continue
1065   case "$partition" in
1066     hd?) IDEDISKS="$IDEDISKS $partition";;                # IDE  Harddisk, entire disk
1067     sd?) ;;                                               # SCSI Harddisk, entire disk
1068 #    [hs]d*) partitions="$partitions /dev/$partition";;    # IDE or SCSI disk partition
1069     [hs]d*|ub*) partitions="$partitions /dev/$partition";;    # IDE, USB or SCSI disk partition
1070   esac
1071 done <<EOT
1072 $(awk 'BEGIN{old="__start"}{if($0==old){exit}else{old=$0;if($4&&$4!="name"){print $0}}}' /proc/partitions)
1073 EOT
1074 }
1075 check_partitions 1>/dev/null 2>&1 # avoid output "check_partitions:3: read-only file system"
1076 # }}}
1077
1078 # {{{ Enable DMA for all IDE drives now if not disabled
1079 # Notice: Already done by linuxrc, but make sure it's done also on harddisk-installed systems
1080 config_dma(){
1081 if checkbootparam 'nodma'; then
1082   ewarn "Skipping DMA accelleration as requested on boot commandline." ; eend 0
1083 else
1084   for d in $(cd /proc/ide 2>>$DEBUG && echo hd[a-z]); do
1085     if test -d /proc/ide/$d; then
1086       if egrep -q 'using_dma[ \t]+0' /proc/ide/$d/settings 2>>$DEBUG; then
1087         MODEL="$(cat /proc/ide/$d/model 2>>$DEBUG)"
1088         test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]"
1089         einfo "Enabling DMA acceleration for: ${WHITE}$d        ${YELLOW}[${MODEL}]${NORMAL}"
1090         echo "using_dma:1" >/proc/ide/$d/settings
1091         eend 0
1092       fi
1093     fi
1094   done
1095 fi
1096 }
1097 # }}}
1098
1099 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
1100 config_fstab(){
1101
1102 NOSWAP="yes" # we do not use swap by default!
1103 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
1104    NOSWAP=''
1105    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
1106 fi
1107
1108 if checkbootparam 'nofstab' || checkbootparam 'forensic' ; then
1109   ewarn "Skipping /etc/fstab creation as requested on boot commandline." ; eend 0
1110 else
1111   einfo "Scanning for harddisk partitions and creating /etc/fstab. (Disable this via boot option: nofstab)"
1112   iszsh && setopt nonomatch
1113   if [ -x /usr/sbin/rebuildfstab ] ; then
1114      config_userfstab || fstabuser=grml
1115      /usr/sbin/rebuildfstab -r -u $fstabuser -g $fstabuser ; eend $?
1116   else
1117      ewarn "Command rebuildfstab not found. Install package grml-rebuildfstab." ; eend 1
1118   fi
1119 fi # checkbootparam nofstab/forensic
1120
1121 # Scan for swap, config, homedir - but only in live-mode
1122 if [ -z "$INSTALLED" ] ; then
1123    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
1124    GRML_IMG=""
1125    GRML_SWP=""
1126    HOMEDIR="$(getbootparam 'home')"
1127    if [ -n "$partitions" ]; then
1128       while read p m f relax; do
1129         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
1130         partoptions="users,exec"
1131         fnew=""
1132         # it's a swap partition?
1133         case "$f" in swap)
1134           eindent
1135           if [ -n "$NOSWAP" ]; then
1136              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
1137              eend 0
1138           else
1139              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
1140                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
1141                      if [ -n "$ANYSWAP" ] ; then
1142                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
1143                         swapon $p 2>>$DEBUG ; eend $?
1144                      else
1145                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
1146                      fi
1147                      ;;
1148                    *)
1149                      if [[ "$p" == LABEL* ]] ; then
1150                         p=$(blkid -t $p | awk -F: '{print $1}')
1151                      fi
1152                      if grep -q $p /proc/swaps ; then
1153                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
1154                      else
1155                         if [ -b "$p" ] ; then
1156                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
1157                         swapon $p 2>>$DEBUG ; eend $?
1158                         else
1159                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
1160                         fi
1161                      fi
1162                      ;;
1163              esac # dd-check
1164           fi # -n "$NOSWAP
1165           eoutdent
1166           continue
1167           ;;
1168         esac # it's a swap partition?
1169
1170         # mount read-only
1171         MOUNTOPTS="ro"
1172         case "$f" in
1173           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
1174           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
1175           *) continue ;;
1176           # *) NONEFOUND='1'; continue ;;
1177         esac
1178
1179         # use a swapfile
1180         if [ -z "$NOSWAP" ] ; then
1181            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
1182            # Activate swapfile, if exists
1183            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
1184         fi
1185         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
1186            mount -o remount,rw $m && MOUNTED=1
1187            if swapon "$SWAPFILE" 2>>$DEBUG ; then
1188               eindent
1189                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
1190               eoutdent
1191               fnew="$SWAPFILE swap swap defaults 0 0"
1192               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
1193               GRML_SWP="$GRML_SWP $SWAPFILE"
1194               eend 0
1195            fi
1196            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
1197         fi
1198
1199         # use a image as home
1200         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
1201         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
1202            if [ -n "$HOMEDIR" ]; then
1203               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
1204                  continue
1205               fi
1206            fi
1207            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
1208               GRML_IMG="$IMAGE"
1209               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
1210            fi
1211         fi
1212         eend 0
1213
1214         # Umount, if not in use
1215         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
1216
1217       done <<EOT
1218       $(cat /etc/fstab)
1219 EOT
1220    fi # -n $partitions
1221 fi # -z $INSTALLED
1222 }
1223 # }}}
1224
1225 # {{{ Mouse
1226 config_mouse(){
1227 if [ -n "$MOUSE_DEVICE" ] ; then
1228   einfo "Detecting mouse: ${MOUSE_FULLNAME} at ${MOUSE_DEVICE}" ; eend $?
1229 fi
1230 }
1231 # }}}
1232
1233 # {{{ IPv6 configuration
1234 # Load IPv6 kernel module and print IP adresses
1235 config_ipv6(){
1236 if checkbootparam 'ipv6'; then
1237   einfo "Enabling IPv6 as requested on boot commandline (sleeping for 2 seconds)"
1238   modprobe ipv6
1239   # we probably need some time until stateless autoconfiguration has happened
1240   sleep 2
1241   NETDEVICES="$(awk -F: '/eth.:|tr.:|wlan.:/{print $1}' /proc/net/dev 2>>$DEBUG)"
1242   for DEVICE in `echo "$NETDEVICES"`; do
1243     eindent
1244       einfo "$DEVICE:"
1245       ADDRESSES="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{print $3}')"
1246       COUNT="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{ sum += 1};END {print sum }')"
1247       eindent
1248         for ADDR in `echo "$ADDRESSES"` ; do
1249             einfo "$ADDR"
1250         done
1251         if [ "$COUNT" -eq "0" ] ; then
1252            einfo "(none)" ; eend 1
1253         fi
1254       eoutdent
1255     eoutdent
1256   done
1257   eend 0
1258 fi
1259 }
1260 # }}}
1261
1262 # {{{ Fat-Client-Version: DHCP Broadcast for IP address
1263 config_dhcp(){
1264 if checkbootparam 'nodhcp'; then
1265   ewarn "Skipping DHCP broadcast/network detection as requested on boot commandline." ; eend 0
1266 else
1267   NETDEVICES="$(awk -F: '/eth.:|tr.:|wlan.:/{print $1}' /proc/net/dev 2>>$DEBUG)"
1268   rm -rf /etc/network/status ; mkdir -p /etc/network/status
1269   for DEVICE in `echo "$NETDEVICES"` ; do
1270     einfo "Network device ${WHITE}${DEVICE}${NORMAL} detected, DHCP broadcasting for IP. (Backgrounding)"
1271     trap 2 3 11
1272     ifconfig $DEVICE up >>$DEBUG 2>&1
1273     ( pump -i $DEVICE >>$DEBUG 2>&1 && echo finished_running_pump > /etc/network/status/$DEVICE ) &
1274     trap "" 2 3 11
1275     sleep 1
1276     eend 0
1277   done
1278   if [ -n "$INSTALLED" ] ; then
1279      ewarn 'If you want to disable automatic DHCP requests set CONFIG_DHCP=no in /etc/grml/autoconfig.'
1280      eend 0
1281   fi
1282 fi
1283 }
1284 # }}}
1285
1286 # {{{ helper functions
1287 findfile(){
1288 FOUND=""
1289 # search all partitions for a file in the root directory
1290 for i in /mnt/[sh]d[a-z] /mnt/[sh]d[a-z][1-9] /mnt/[sh]d[a-z][1-9]?*; do
1291 # See if it's already mounted
1292   [ -f "$i/$1" ] &&  { echo "$i/$1"; return 0; }
1293   if [ -d "$i" ] && mount -r "$i" 2>>$DEBUG; then
1294     [ -f "$i/$1" ] && FOUND="$i/$1"
1295     umount -l "$i" 2>>$DEBUG
1296     [ -n "$FOUND" ] && { echo "$FOUND"; return 0; }
1297   fi
1298 done
1299 return 2
1300 }
1301
1302 fstype(){
1303 case "$(file -s $1)" in
1304   *[Ff][Aa][Tt]*|*[Xx]86*) echo "vfat"; return 0;;
1305   *[Rr][Ee][Ii][Ss][Ee][Rr]*)  echo "reiserfs"; return 0;;
1306   *[Xx][Ff][Ss]*)  echo "xfs"; return 0;;
1307   *[Ee][Xx][Tt]3*) echo "ext3"; return 0;;
1308   *[Ee][Xx][Tt]2*) echo "ext2"; return 0;;
1309   *data*)          echo "invalid"; return 0;;
1310   *) echo "auto"; return 0;;
1311 esac
1312 }
1313
1314 # Try to mount this filesystem read-only, without or with encryption
1315 trymount(){
1316 # Check if already mounted
1317 case "$(cat /proc/mounts)" in *\ $2\ *) return 0;; esac
1318 # Apparently, mount-aes DOES autodetect AES loopback files.
1319 [ -b "$1" ] && { mount -t auto -o ro "$1" "$2" 2>>$DEBUG; RC="$?"; }
1320 # We need to mount crypto-loop files with initial rw support
1321 [ -f "$1" ] && { mount -t auto -o loop,rw "$1" "$2" 2>>$DEBUG; RC="$?"; }
1322 # Mount succeeded?
1323 [ "$RC" = "0" ] && return 0
1324 echo ""
1325 einfo "Filesystem not autodetected, trying to mount $1 with AES256 encryption."
1326 a="y"
1327 while [ "$a" != "n" -a "$a" != "N" ]; do
1328 # We need to mount crypto-loop files with initial rw support
1329  mount -t auto -o loop,rw,encryption=AES256 "$1" "$2" && return 0
1330  echo -n "${RED}Mount failed, retry? [Y/n] ${NORMAL}"
1331  # Problem with ioctl() from getpasswd()?
1332  # read a
1333  read a
1334 done
1335 return 1
1336 }
1337 # }}}
1338
1339 # {{{ CPU-detection
1340 config_cpu(){
1341 if checkbootparam 'nocpu'; then
1342   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
1343 else
1344   # check module dependencies
1345   cpufreq_check() {
1346    if ! [ -e /lib/modules/${KERNEL}/kernel/arch/x86/kernel/cpu/cpufreq ] ; then
1347       if [ -e /lib64 ] ; then
1348          [ -e /lib/modules/${KERNEL}/kernel/arch/x86_64/kernel/cpufreq ] || return 1
1349       else
1350          [ -e /lib/modules/${KERNEL}/kernel/arch/i386/kernel/cpu/cpufreq -o ! -e /lib/modules/${KERNEL}/kernel/drivers/cpufreq ] || return 1
1351       fi
1352    fi
1353   }
1354
1355   if [[ `grep -c processor /proc/cpuinfo` -gt 1 ]] ; then
1356      einfo "Detecting CPU:"
1357      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)
1358      echo $CPU | sed 's/ \{1,\}/ /g'
1359      eend 0
1360   else
1361      einfo "Detecting 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
1362   fi
1363
1364   # Disclaimer: sorry for the tons of if/then/else... but this makes sure we use:
1365   # * it only if we have the according kernel modules available
1366   # * cpufreq only on laptops (check via /usr/sbin/laptop-detect) and not inside Virtual Box
1367   # * current version of /etc/init.d/loadcpufreq from Debian (to stay in sync)
1368   #   -> parse output of the initscript and output it according to our look'n'feel
1369   # * our own cpufreq-detect.sh if /etc/init.d/loadcpufreq isn't present
1370   if ! cpufreq_check ; then
1371     ewarn "Skipping cpufreq setup as module dependencies are not fulfilled." ; eend 1
1372   else
1373     if /usr/sbin/laptop-detect 1>/dev/null 2>&1 ; then
1374        # Virtual Box supports ACPI and laptop-detect returns with '0', so check for it:
1375        if [ -r /proc/acpi/battery/BAT0/info ] ; then
1376           if grep -q 'OEM info:                innotek' /proc/acpi/battery/BAT0/info ; then
1377              einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0
1378              return 0
1379           fi
1380        fi
1381        einfo "Detected Laptop - trying to use cpu frequency scaling:"
1382        eindent
1383        if [ -x /etc/init.d/loadcpufreq ] ; then
1384           SKIP_CPU_GOVERNOR=''
1385           LOADCPUFREQ=$(mktemp)
1386           /etc/init.d/loadcpufreq start >"$LOADCPUFREQ" 2>&1 ; RC=$?
1387           if grep -q FATAL "$LOADCPUFREQ" ; then
1388              eindent
1389                SKIP_CPU_GOVERNOR=1
1390                oldIFS="$IFS"
1391                IFS="
1392 "
1393                 for line in $(grep FATAL "$LOADCPUFREQ" | sed 's/.*FATAL: //; s/ (.*)//') ; do
1394                     eerror "$line" ; eend $RC
1395                 done
1396                 IFS="$oldIFS"
1397              eoutdent
1398            elif grep -q done "$LOADCPUFREQ" ; then
1399              MODULE=$(grep done "$LOADCPUFREQ" | sed 's/.*done (\(.*\))./\1/')
1400              if [ -n "$MODULE" -a "$MODULE" != none ]; then
1401                 einfo "Loading cpufreq kernel module $MODULE" ; eend 0
1402              else
1403                 ewarn "Could not find an appropriate kernel module for cpu frequency scaling." ; eend 1
1404              fi
1405           fi
1406           rm -f $LOADCPUFREQ
1407        elif [ -r /usr/bin/cpufreq-detect.sh ] ; then
1408           . /usr/bin/cpufreq-detect.sh
1409           if [ -n "$MODULE" -a "$MODULE" != none ]; then
1410              einfo "Loading modules ${MODULE}"
1411              modprobe "$MODULE" 1>>$DEBUG || modprobe "$MODULE_FALLBACK" 1>>$DEBUG
1412              RC=$?
1413              if [[ $RC == 0 ]]; then
1414                 eend 0
1415              else
1416                 SKIP_CPU_GOVERNOR=1
1417                 eend $1
1418              fi
1419           else
1420              ewarn "Could not detect an appropriate CPU for use with cpu frequency scaling - skipping." && eend 1
1421           fi # $MODULE
1422        fi # loadcpufreq
1423
1424        if [ -z "$SKIP_CPU_GOVERNOR" ] ; then
1425           einfo "Loading cpufreq_ondemand, setting ondemand governor"
1426           if modprobe cpufreq_ondemand ; RC=$? ; then
1427              for file in $(find /sys/devices/system/cpu/ -name scaling_governor 2>/dev/null) ; do
1428                  echo ondemand > $file
1429              done
1430           fi
1431           eend $RC
1432        fi # cpu-governor
1433
1434        eoutdent
1435
1436     fi # laptop-detect
1437   fi # cpufreq_check
1438 fi # checkbootparam nocpu
1439 }
1440 # }}}
1441
1442 # {{{ autostart of ssh
1443 config_ssh(){
1444 if checkbootparam 'ssh' ; then
1445    SSH_PASSWD=''
1446    SSH_PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
1447    einfo "Bootoption ssh found, trying to set password for user grml."
1448    eindent
1449    if [ -z "$SSH_PASSWD" ] ; then
1450       if [ -x /usr/bin/apg ] ; then
1451          SSH_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1452       elif [ -x /usr/bin/gpw ] ; then
1453          SSH_PASSWD="$(gpw 1)"
1454       elif [ -x /usr/bin/pwgen ] ; then
1455          SSH_PASSWD="$(pwgen -1 8)"
1456       elif [ -x /usr/bin/hexdump ] ; then
1457          SSH_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1458       elif [ -n "$RANDOM" ] ; then
1459          SSH_PASSWD="grml${RANDOM}"
1460       else
1461          SSH_PASSWD=''
1462          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1463          eend 1
1464       fi
1465
1466       if [ -n "$SSH_PASSWD" ] ; then
1467          ewarn "No given password for ssh found. Using random password: $SSH_PASSWD" ; eend 0
1468       fi
1469    fi
1470    eoutdent
1471
1472    # finally check if we have a password we can use:
1473    if [ -n "$SSH_PASSWD" ] ; then
1474       # chpasswd sucks, seriously.
1475       if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1476         echo "grml:$SSH_PASSWD" | chpasswd -m
1477       else
1478         echo "grml:$SSH_PASSWD" | chpasswd
1479       fi
1480    fi
1481
1482    einfo 'Starting secure shell server in background.'
1483    /etc/init.d/rmnologin start 1>>$DEBUG 2>>$DEBUG
1484    /etc/init.d/ssh start 1>>$DEBUG 2>>$DEBUG &
1485    eend $?
1486
1487    eindent
1488    ewarn 'Warning: please change the password for user grml as soon as possible!'
1489    eoutdent
1490 fi
1491 }
1492 # }}}
1493
1494 # {{{ set password for user grml
1495 config_passwd(){
1496 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1497   einfo "Bootoption passwd found."
1498   PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1499   if [ -n "$PASSWD" ] ; then
1500     echo "grml:$PASSWD" | chpasswd -m ; eend $?
1501   else
1502     eerror "No given password for ssh found. Autostart of SSH will not work." ; eend 1
1503   fi
1504   eindent
1505     ewarn "Warning: please change the password for user grml set via bootparameter as soon as possible!"
1506   eoutdent
1507 fi
1508 }
1509 # }}}
1510
1511 # {{{ Check for persistent homedir option and eventually mount /home from there, or use a loopback file.
1512 config_homedir(){
1513 if checkbootparam 'home' ; then
1514    HOMEDIR="$(getbootparam 'home')"
1515    MYHOMEDEVICE=""
1516    MYHOMEMOUNTPOINT=""
1517    MYHOMEDIR=""
1518    if [ -n "$HOMEDIR" ]; then
1519       einfo "Bootoption home detected." && eend 0
1520       case "$HOMEDIR" in
1521         /dev/*)
1522         MYHOMEDEVICE="${HOMEDIR##/dev/}"
1523         MYHOMEDEVICE="/dev/${MYHOMEDEVICE%%/*}"
1524         MYHOMEMOUNTPOINT="/mnt/${MYHOMEDEVICE##/dev/}"
1525         MYHOMEDIR="/mnt/${HOMEDIR##/dev/}"
1526       ;;
1527         /mnt/*)
1528         MYHOMEDEVICE="${HOMEDIR##/mnt/}"
1529         MYHOMEDEVICE="/dev/${MYHOMEDEVICE%%/*}"
1530         MYHOMEMOUNTPOINT="/mnt/${MYHOMEDEVICE##/dev/}"
1531         MYHOMEDIR="$HOMEDIR"
1532       ;;
1533         [Aa][Uu][Tt][Oo]|[Ss][Cc][Aa][Nn]|[Ff][Ii][Nn][Dd])
1534         MYHOMEDIR="$(findfile grml.img)"
1535         MYHOMEDEVICE="${MYHOMEDIR##/mnt/}"
1536         MYHOMEDEVICE="/dev/${MYHOMEDEVICE%%/*}"
1537         MYHOMEMOUNTPOINT="/mnt/${MYHOMEDEVICE##/dev/}"
1538       ;;
1539       *)
1540         eerror "Invalid home= option '$HOMEDIR' specified (must start with /dev/ or /mnt/ or 'scan')." ; eend 1
1541         eerror "Option ignored." ; eend 1
1542       ;;
1543       esac
1544    fi # -n $HOMEDIR
1545
1546    if [ -n "$MYHOMEDIR" ]; then
1547       if trymount "$MYHOMEDEVICE" "$MYHOMEMOUNTPOINT"; then
1548          [ -f "$MYHOMEMOUNTPOINT/grml.img" ] && MYHOMEDIR="$MYHOMEMOUNTPOINT/grml.img"
1549          while read device mountpoint fs relax; do
1550            case "$mountpoint" in *$MYHOMEMOUNTPOINT*)
1551              case "$fs" in
1552                *[Nn][Tt][Ff][Ss]*)
1553                  umount "$MYHOMEMOUNTPOINT"; eerror "Error: will not mount NTFS filesystem on $MYHOMEDEVICE read/write!" ; eend 1
1554                  break
1555                  ;;
1556                *[Ff][Aa][Tt]*)
1557                  # Note: This currently won't work with encrypted partitions
1558                  umount "$MYHOMEMOUNTPOINT"; mount -t vfat -o rw,uid=grml,gid=grml,umask=002 "$MYHOMEDEVICE" "$MYHOMEMOUNTPOINT"
1559                  if [ ! -f "$MYHOMEDIR" ]; then
1560                     ewarn "WARNING: FAT32 is not a good filesystem option for /home/grml (missing socket/symlink support)."
1561                     ewarn "WARNING: Better use an ext2 loopback file on this device, and boot with home=$MYHOMEDEVICE/grml.img."
1562                  fi
1563                  ;;
1564              esac
1565
1566              if mount -o remount,rw "$MYHOMEMOUNTPOINT"; then
1567                 einfo "Mounting ${WHITE}$MYHOMEDIR${NORMAL} as ${WHITE}/home/grml${NORMAL}."
1568                 if [ -f "$MYHOMEDIR" ]; then
1569                    # It's a loopback file, mount it over the /home/grml directory
1570                    trymount "$MYHOMEDIR" /home/grml
1571                    RC="$?"
1572                    [ "$RC" = "0" ] && ERROR="$(mount -o remount,rw /home/grml 2>&1)"
1573                    RC="$?"
1574                 else
1575                    # Do a --bind mount
1576                    ERROR="$(mount --bind "$MYHOMEDIR" /home/grml 2>&1)"
1577                    RC="$?"
1578                 fi # -f $MYHOMEDIR
1579
1580                 [ "$RC" = "0" ] && eend 0 || ( eerror "${ERROR}" ; eend 1 )
1581
1582              fi #  mount -o remount,rw,...
1583            break
1584            ;;
1585            esac # case "$mountpoint" in *$MYHOMEMOUNTPOINT*)
1586          done <<EOT
1587          $(cat /proc/mounts)
1588 EOT
1589      fi # if trymount ...
1590    fi # -n $MYHOMEDIR
1591 fi # checkbootparam home
1592 }
1593 # }}}
1594
1595 # {{{ Sound
1596 config_mixer(){
1597 if ! [ -x /usr/bin/aumix ] ; then
1598   eerror "aumix binary not available. Can not set sound volumes therefore." ; eend 1
1599 else
1600
1601   if ! [ -r /proc/asound/cards ] ; then
1602      ewarn "No soundcard present, skipping mixer settings therefore." ; eend 0
1603      return
1604   fi
1605
1606   if checkbootparam 'vol' ; then
1607     VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1608     if [ -z "$VOL" ] ; then
1609       eerror "Bootoption vol found but no volume level/parameter given. Using defaults." ; eend 1
1610       VOL='75' # default
1611     fi
1612   else
1613     VOL='75' # default
1614   fi
1615
1616   if checkbootparam 'nosound' ; then
1617     einfo "Muting sound devices on request."
1618     # some IBM notebooks require the following stuff:
1619     if [ -x /usr/bin/amixer ] ; then
1620        if amixer get Front 1>/dev/null 2>>$DEBUG ; then
1621           amixer set Front unmute 1>/dev/null
1622           amixer set Front 0% 1>/dev/null
1623        fi
1624     fi
1625     ERROR=$(aumix -w 0 -v 0 -p 0 -m 0 2>&1) ; RC=$?
1626     if [ -n "$ERROR" ] ; then
1627        eindent
1628        eerror "Problem muting sound devices: $ERROR"
1629        eoutdent
1630     fi
1631     eend $RC
1632   elif [ -z "$INSTALLED" ]; then
1633       einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1634       # some IBM notebooks require the following stuff:
1635       if [ -x /usr/bin/amixer ] ; then
1636          if amixer get Front 1>/dev/null 2>>$DEBUG ; then
1637             amixer set Front unmute 1>/dev/null
1638             amixer set Front ${VOL}% 1>/dev/null
1639          fi
1640       fi
1641       # by default assume '0' as volume for microphone:
1642       if checkbootparam 'micvol' ; then
1643          MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1644       else
1645          MICVOL=0
1646       fi
1647
1648       # finally set the volumes:
1649       ERROR=$(aumix -w $VOL -v $VOL -p $VOL -m $MICVOL 2>&1) ; RC=$?
1650       if [ -n "$ERROR" ] ; then
1651          eindent
1652          eerror "Problem setting mixer volumes: $ERROR (no soundcard?)"
1653          eoutdent
1654       fi
1655       eend $RC
1656   fi
1657
1658 fi
1659 }
1660 # }}}
1661
1662 # {{{ modem detection
1663 config_modem(){
1664 if checkbootparam 'nomodem'; then
1665   ewarn "Skipping check for AC97 modem controller as requested on boot commandline." ; eend 0
1666 else
1667   if [ -x /etc/init.d/sl-modem-daemon ] ; then
1668      if lspci | grep Intel | grep -q "AC'97 Modem Controller" ; then
1669         einfo "AC97 modem controller detected. Start it running 'Start sl-modem-daemon'."
1670         eend 0
1671      fi
1672   fi
1673 fi
1674 }
1675 # }}}
1676
1677 # {{{ keyboard add-ons
1678 config_setkeycodes(){
1679 if checkbootparam 'setkeycodes' ; then
1680  einfo "Setting keycodes as requested via bootparameter 'setkeycodes'."
1681   # MS MM keyboard add-on
1682   # fix
1683   setkeycodes e001 126 &>/dev/null
1684   setkeycodes e059 127 &>/dev/null
1685   # fn keys
1686   setkeycodes e03b 59 &>/dev/null
1687   setkeycodes e008 60 &>/dev/null
1688   setkeycodes e007 61 &>/dev/null
1689   setkeycodes e03e 62 &>/dev/null
1690   setkeycodes e03f 63 &>/dev/null
1691   setkeycodes e040 64 &>/dev/null
1692   setkeycodes e041 65 &>/dev/null
1693   setkeycodes e042 66 &>/dev/null
1694   setkeycodes e043 67 &>/dev/null
1695   setkeycodes e023 68 &>/dev/null
1696   setkeycodes e057 87 &>/dev/null
1697   setkeycodes e058 88 &>/dev/null
1698   # hp keycodes
1699   setkeycodes e00a 89 e008 90 &>/dev/null
1700  eend 0
1701 fi
1702 }
1703 # }}}
1704
1705 # {{{ wondershaper
1706 config_wondershaper(){
1707  if checkbootparam 'wondershaper' ; then
1708     WONDER="$(getbootparam 'wondershaper' 2>>$DEBUG)"
1709     CMD=wondershaper
1710     DEVICE=""
1711     DOWNSTREAM=""
1712     UPSTREAM=""
1713     if [ -n "$WONDER" ]; then
1714       # Extra options
1715       DEVICE="${WONDER%%,*}"
1716       R="${WONDER#*,}"
1717       if [ -n "$R" -a "$R" != "$WONDER" ]; then
1718         WONDER="$R"
1719         DOWNSTREAM="${WONDER%%,*}"
1720         R="${WONDER#*,}"
1721         if [ -n "$R" -a "$R" != "$WONDER" ]; then
1722           WONDER="$R"
1723           UPSTREAM="${WONDER%%,*}"
1724           R="${WONDER#*,}"
1725         fi
1726       fi
1727     fi
1728     [ -n "$DEVICE" ]     && CMD="$CMD $DEVICE"
1729     [ -n "$DOWNSTREAM" ] && CMD="$CMD $DOWNSTREAM"
1730     [ -n "$UPSTREAM" ]   && CMD="$CMD $UPSTREAM"
1731     einfo "Starting wondershaper (${CMD}) in background."
1732     ( sh -c $CMD & ) && eend 0
1733  fi
1734 }
1735 # }}}
1736
1737 # {{{ syslog-ng
1738 config_syslog(){
1739  if checkbootparam 'nosyslog'; then
1740     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1741  else
1742     SYSLOGD=''
1743     [ -x /etc/init.d/syslog-ng ] && SYSLOGD='syslog-ng'
1744     [ -x /etc/init.d/rsyslog   ] && SYSLOGD='rsyslog'
1745     [ -x /etc/init.d/dsyslog   ] && SYSLOGD='dsyslog'
1746     [ -x /etc/init.d/sysklogd  ] && SYSLOGD='sysklogd'
1747     [ -x /etc/init.d/inetutils-syslogd ] && SYSLOGD='inetutils-syslogd'
1748
1749     if [ -z "$SYSLOGD" ] ; then
1750        eerror "No syslog daemon found." ; eend 1
1751     else
1752        einfo "Starting $SYSLOGD in background."
1753        /etc/init.d/$SYSLOGD start 1>>$DEBUG &
1754        eend 0
1755     fi
1756  fi
1757 }
1758 # }}}
1759
1760 # {{{ gpm
1761 config_gpm(){
1762  if checkbootparam 'nogpm'; then
1763   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1764  else
1765    if ! [ -r /dev/input/mice ] ; then
1766       eerror "No mouse found - not starting GPM." ; eend 1
1767    else
1768       einfo "Starting gpm in background."
1769       /etc/init.d/gpm start 1>>$DEBUG &
1770       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start 1>>$DEBUG ) &
1771       eend 0
1772    fi
1773  fi
1774 }
1775 # }}}
1776
1777 # {{{ services
1778 config_services(){
1779  if checkbootparam 'services' ; then
1780     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1781     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1782     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1783     einfo "Starting service(s) ${SERVICENL} in background."
1784     for service in $(echo -e $SERVICELIST) ; do
1785        /etc/init.d/${service} start 1>>$DEBUG &
1786     done
1787     [ "$?" == "0" ] ; eend $?
1788  fi
1789 }
1790 # }}}
1791
1792 # {{{ config files
1793 config_netconfig(){
1794  if checkbootparam 'netconfig' ; then
1795   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1796   CONFIGFILE='/tmp/netconfig.grml'
1797
1798   getconfig() {
1799   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 \
1800        --read-timeout=10 $CONFIG -O $CONFIGFILE && return 0 || return 1
1801   }
1802   einfo "Trying to get ${WHITE}${CONFIG}${NORMAL}"
1803   counter=10
1804   while ! getconfig && [[ "$counter" != 0 ]] ; do
1805     echo -n "Sleeping for 5 seconds and trying to get config again... "
1806     counter=$(( counter-1 ))
1807     echo "$counter tries left" ; sleep 1
1808   done
1809   if [ -r "$CONFIGFILE" ] ; then
1810     einfo "Downloading was successfull." ; eend 0
1811     einfo "md5sum of ${WHITE}${CONFIG}${NORMAL}: "
1812     md5sum $CONFIGFILE ; eend 0
1813     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1814   else
1815     einfo "Sorry, could not fetch $CONFIG" ; eend 1
1816   fi
1817  fi
1818 }
1819 # }}}
1820
1821 # {{{ blindsound
1822 config_blindsound(){
1823  if checkbootparam 'blind' ; then
1824     beep
1825     flitewrapper "welcome to the gremel system"
1826  fi
1827 }
1828 # }}}
1829
1830 # {{{ welcome sound
1831 config_welcome(){
1832  if checkbootparam 'welcome' ; then
1833     flitewrapper "welcome to the gremel system"
1834  fi
1835 }
1836 # }}}
1837
1838 # {{{ fix/workaround for unionfs
1839 fix_unionfs(){
1840   if [ -z "$INSTALLED" ]; then
1841    touch /var/cache/apt/*cache.bin
1842   fi
1843 }
1844 # }}}
1845
1846 # {{{ create all /mnt-directories
1847 create_mnt_dirs(){
1848   ewarn "create_mnt_dirs is deprecated as grml-rebuildfstab does all we need."
1849   ewarn "Please set CONFIG_CREATE_MNT_DIRS='no' in /etc/grml/autoconfig" ; eend 0
1850 }
1851 # }}}
1852
1853 # {{{ start X window system via grml-x
1854 config_x_startup(){
1855 # make sure we start X only if startx is used *before* a nostartx option
1856 # so it's possible to disable automatic X startup using nostart
1857 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1858  if [ -x /usr/X11R6/bin/X ] ; then
1859   if [ -z "$INSTALLED" ] ; then
1860    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1861    if [ -z "$WINDOWMANAGER" ] ; then
1862      einfo "No window manager specified. Taking ${WHITE}wm-ng${NORMAL} as default." && eend 0
1863      WINDOWMANAGER="wm-ng"
1864    else
1865      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1866    fi
1867    einfo "Changing to runlevel 5 for starting grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1868    config_userfstab || fstabuser='grml'
1869  cat>|/etc/init.d/xstartup<<EOF
1870 #!/bin/sh
1871 # su - $fstabuser -c 'grml-x "$WINDOWMANAGER"'
1872 sudo -u $fstabuser -i /usr/bin/grml-x $WINDOWMANAGER 1>>$DEBUG
1873 EOF
1874    chmod 755 /etc/init.d/xstartup
1875
1876    # adjust inittab for xstartup
1877    if grep -q '^6:' /etc/inittab ; then
1878       sed -i 's|^6:.*|6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /bin/zsh"|' /etc/inittab
1879    else # just append tty6 to inittab if no definition is present:
1880       echo '6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /bin/zsh"' >> /etc/inittab
1881    fi
1882
1883    /sbin/telinit q ; eend $?
1884
1885    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1886       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1887    else
1888       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1889    fi
1890
1891   else
1892     eerror "We are not running in live mode - startx will not work, skipping it."
1893     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1894   fi
1895  else
1896    eerror "/usr/X11R6/bin/X is not present on this grml flavour."
1897    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1898  fi
1899 fi
1900 }
1901 # }}}
1902
1903 # {{{ configuration framework
1904 config_extract(){
1905 if checkbootparam 'extract' ; then
1906  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1907  EXTRACTOPTIONS="-- -x $EXTRACT"
1908 fi
1909 }
1910
1911 config_finddcsdir() {
1912 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1913 #    on the command line, nothing is changed and the dcs files are
1914 #    searched within the .iso, $dcs-dir is set to the root directory
1915 #    within the .iso
1916 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1917 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1918 #    set, $dcs-dir is set to the root directory within the .iso.
1919 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1920 #    foo, even if a GRMLCFG partition is present.
1921 DCSDIR=""
1922 if checkbootparam 'noautoconfig' || checkbootparam 'forensic' ; then
1923   ewarn "Skipping running automount of device(s) labeled GRMLCFG as requested." ; eend 0
1924 else
1925   if [ -z "$INSTALLED" ] ; then
1926     if checkbootparam 'myconfig' ; then
1927       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1928       if [ -z "$DCSDEVICE" ]; then
1929         einfo "No device for bootoption myconfig provided." ; eend 1
1930       fi # [ -z "$DCSDEVICE" ]
1931     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1932       einfo "Searching for device(s) labeled with GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1933       eindent
1934       # We do need the following fix so floppy disk is available to blkid in any case :-/
1935       if [ -r /dev/fd0 ] ; then
1936         einfo "Floppy device detected. Trying to access floppy disk."
1937         if timeout 4 dd if=/dev/fd0 of=/dev/null bs=512 count=1 1>>$DEBUG 2>&1 ; then
1938            blkid /dev/fd0 1>>$DEBUG 2>&1
1939         fi
1940       fi
1941       DCSDEVICE=$(blkid -t LABEL=GRMLCFG | head -1 | awk -F: '{print $1}')
1942     fi
1943     if [ -n "$DCSDEVICE" ]; then
1944       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1945       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1946       if [ -n "$DCSDIR" ]; then
1947         einfo "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1948       else
1949         [ -d /mnt/grml ] || mkdir /mnt/grml
1950         umount /mnt/grml 1>>$DEBUG 2>&1 # make sure it is not mounted
1951         mount -o ro -t auto $DCSDEVICE  /mnt/grml ; RC="$?"
1952         if [[ $RC == 0 ]]; then
1953           einfo "Successfully mounted $DCSDEVICE to /mnt/grml (readonly)." ; eend 0
1954           eindent
1955         fi
1956         DCSDIR="/mnt/grml"
1957       fi
1958     fi
1959   fi
1960 fi
1961
1962 if [ -n "$DCSDIR" ]; then
1963   einfo "Debs, config, scripts will be read from $DCSDIR." ; eend 0
1964 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1965   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1966 fi
1967 }
1968
1969
1970 config_partconf() {
1971 if checkbootparam 'partconf' ; then
1972  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1973  if [ -n "$MOUNTDEVICE" ]; then
1974    [ -d /mnt/grml ] || mkdir /mnt/grml
1975    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1976     if [[ $RC == 0 ]]; then
1977       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1978       einfo "Copying files from $MOUNTDEVICE over grml system."
1979       for file in `cat /etc/grml/partconf` ; do
1980         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1981         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1982       done && eend 0
1983     else
1984       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1985     fi # mount $MOUNTDEVICE
1986    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1987  else
1988    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1989  fi # [ -n "$MOUNTDEVICE" ]
1990 fi
1991 }
1992 # }}}
1993
1994 # {{{ /cdrom/.*-options
1995 config_debs(){
1996 if checkbootparam 'debs' ; then
1997    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1998    if ! echo $DEBS | grep -q '/'; then
1999      # backwards compatibility: if no path is given get debs from debs/
2000      DEBS="debs/$DEBS"
2001    fi
2002    einfo "Tring to install debian package(s) ${DEBS}"
2003    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
2004    dpkg -i $DEBS ; eend $?
2005 fi
2006 }
2007
2008 config_scripts(){
2009 if checkbootparam 'scripts' ; then
2010    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
2011    if [ -z "$SCRIPTS" ]; then
2012      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
2013    fi
2014    if ! echo $SCRIPTS | grep -q '/'; then
2015      # backwards compatibility: if no path is given get scripts from scripts/
2016      SCRIPTS="scripts/$SCRIPTS"
2017    fi
2018    SCRIPTS="${DCSDIR}/$SCRIPTS"
2019    if [ -d "$SCRIPTS" ]; then
2020      einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
2021      run-parts $SCRIPTS
2022    else
2023      einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
2024      sh -c $SCRIPTS
2025    fi
2026 fi
2027 }
2028
2029 config_config(){
2030 if checkbootparam 'config' ; then
2031   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
2032   if [ -z "$CONFIG" ]; then
2033     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
2034   fi
2035   if [ -n "$CONFIG" ]; then
2036     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
2037       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
2038
2039       cp -a ${DCSDIR}/${CONFIG}/* /
2040     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
2041       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
2042
2043       cd /
2044       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
2045     else
2046       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
2047     fi
2048   fi
2049 fi
2050 # umount /mnt/grml if it was mounted by finddcsdir
2051 # this doesn't really belong here
2052 grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
2053 }
2054 # }}}
2055
2056 # {{{ mypath
2057 config_mypath(){
2058 if checkbootparam 'mypath' ; then
2059    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
2060    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
2061    touch /etc/grml/my_path
2062    chmod 644 /etc/grml/my_path
2063    # make sure the directories exist:
2064    eindent
2065    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
2066        if ! [ -d "$i" ] ; then
2067           einfo "Creating directory $i"
2068           mkdir -p "$i" ; eend $?
2069        fi
2070    done
2071    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
2072    eoutdent
2073 fi
2074 }
2075 # }}}
2076
2077 # {{{ distcc
2078 config_distcc(){
2079 if checkbootparam 'distcc' ; then
2080  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
2081  if [ -n "$OPTIONS" ]; then
2082     NET=""
2083     INTERFACE=""
2084     if [ -n "$OPTIONS" ]; then
2085       NET="${OPTIONS%%,*}"
2086       R="${OPTIONS#*,}"
2087       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2088         OPTIONS="$R"
2089         INTERFACE="${OPTIONS%%,*}"
2090         R="${OPTIONS#*,}"
2091       fi
2092     fi
2093  fi
2094  CONFIG=/etc/default/distcc
2095  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
2096  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
2097
2098  if [ -n "$INTERFACE" ] ; then
2099    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2100
2101    counter=10
2102    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
2103      counter=$(( counter-1 ))
2104      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
2105      sleep 3
2106      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2107    done
2108  fi
2109
2110  if [ -n "$IP" ] ; then
2111    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
2112
2113    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
2114    eindent
2115     id distccd >/dev/null 2>&1 || \
2116     (
2117       einfo "Creating distcc user" ; \
2118       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
2119     )
2120
2121     einfo "Starting distcc for network ${NET}, listening on ${IP}."
2122    /etc/init.d/distcc start 1>/dev/null ; eend $?
2123    eoutdent
2124  else
2125    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
2126  fi
2127 fi
2128
2129 if checkbootparam 'gcc'; then
2130  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
2131  eindent
2132  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
2133  eoutdent
2134  rm -f /usr/bin/gcc
2135  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
2136 fi
2137
2138 if checkbootparam 'gpp'; then
2139  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
2140  eindent
2141   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
2142   if [ -x /usr/bin/g++-${GPP} ] ; then
2143      rm -f /usr/bin/g++
2144      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
2145   fi
2146   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
2147   if [ -x /usr/bin/cpp-${GPP} ] ; then
2148      rm -f /usr/bin/cpp
2149      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
2150   fi
2151  eoutdent
2152 fi
2153
2154 }
2155 # }}}
2156
2157 # {{{ load modules
2158 # Notice: use it only on live-cd system, if running from harddisk please
2159 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
2160 # in /etc/runlevel.conf
2161 config_modules(){
2162 MODULES_FILE=/etc/grml/modules
2163 if checkbootparam 'nomodules' ; then
2164   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
2165 elif [ -z "$INSTALLED" ]; then
2166  if [ -r $MODULES_FILE ] ; then
2167   einfo "Loading modules specified in ${MODULES_FILE}:"
2168   eindent
2169   grep '^[^#]' $MODULES_FILE | \
2170   while read module args; do
2171     [ "$module" ] || continue
2172       einfo "${module}"
2173       modprobe $module $args ; eend $?
2174   done
2175   eoutdent
2176  else
2177   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
2178  fi
2179 fi
2180 }
2181 # }}}
2182
2183 # {{{ 915resolution
2184 config_915resolution(){
2185 if checkbootparam '915resolution' ; then
2186  OPTIONS="$(getbootparam '915resolution' 2>>$DEBUG)"
2187   if [ -x /usr/sbin/915resolution ]; then
2188     CMD=915resolution
2189     MODE=""
2190     XRESO=""
2191     YRESO=""
2192     if [ -n "$OPTIONS" ]; then
2193       # Extra options
2194       MODE="${OPTIONS%%,*}"
2195       R="${OPTIONS#*,}"
2196       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2197         OPTIONS="$R"
2198         XRESO="${OPTIONS%%,*}"
2199         R="${OPTIONS#*,}"
2200         if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2201           OPTIONS="$R"
2202           YRESO="${OPTIONS%%,*}"
2203           R="${OPTIONS#*,}"
2204         fi
2205       fi
2206     fi
2207     einfo "Running 915resolution with options ${MODE} ${XRESO} ${YRESO}."
2208     [ -n "$MODE" ] && [ -n "$XRESO"  ] && [ -n "$YRESO" ]  && ( sh -c "$CMD $MODE $XRESO $YRESO" & )
2209     eend 0
2210   fi
2211 fi
2212 }
2213 # }}}
2214
2215 # {{{ SW-RAID
2216 config_swraid(){
2217   if [ -z "$INSTALLED" ] ; then
2218   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
2219   if checkbootparam 'noraid'   || checkbootparam 'noswraid' -o \
2220      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
2221      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
2222   else
2223     if ! [ -x /sbin/mdadm ] ; then
2224        eerror "mdadm not available, can not execute it." ; eend 1
2225     else
2226
2227        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2228        # find out whether we have a valid configuration file already
2229        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2230           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
2231           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
2232           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
2233         else
2234           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
2235        fi
2236
2237        if ! checkbootparam 'swraid' ; then
2238           eindent
2239           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
2240           eoutdent
2241        else
2242           einfo "Bootoption swraid found. Searching for software RAID arrays:"
2243           eindent
2244            IFSOLD=${IFS:-}
2245            IFS='
2246 '
2247            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
2248                case $line in
2249                  *'No arrays found'*)
2250                    ewarn "$line" ; eend 0
2251                    ;;
2252                  *)
2253                    einfo "$line" ; eend 0
2254                    ;;
2255                esac
2256            done
2257            IFS=$IFSOLD
2258          eoutdent
2259
2260          if [ -r /proc/mdstat ] ; then
2261             eindent
2262             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
2263             if [ -z "$MDSTAT" ] ; then
2264                ewarn "No active arrays found" ; eend 0
2265             else
2266                IFSOLD=${IFS:-}
2267                IFS='
2268 '
2269                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
2270                    einfo "active arrays: $line" ; eend 0
2271                done
2272                IFS=$IFSOLD
2273             fi
2274             eoutdent
2275          fi # /proc/mdstat
2276        fi # bootoption swraid
2277
2278      fi # is /sbin/mdadm executable?
2279   fi # check for bootoptions
2280   fi # run only in live-cd mode
2281 }
2282 # }}}
2283
2284 # {{{ LVM (Logical Volumes)
2285 config_lvm(){
2286   if [ -z "$INSTALLED" ] ; then
2287   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
2288   if checkbootparam 'nolvm' ; then
2289      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
2290   else
2291     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
2292     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
2293        eerror "LVM not available, can not execute it." ; eend 1
2294     else
2295        if lvdisplay 2>&1 | grep -v 'No volume groups found' 1>/dev/null 2>&1 ; then
2296           einfo "You seem to have logical volumes (LVM) on your system."
2297           eindent
2298           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
2299           eend 0
2300           if checkbootparam 'lvm' ; then
2301              einfo "Bootoption LVM found. Searching for logical volumes:"
2302              /etc/init.d/lvm2 start ; eend $?
2303           fi
2304           eoutdent
2305        fi
2306     fi # check for lvm binary
2307   fi # check for bootoption nolvm
2308   fi # run only in live-cd mode
2309 }
2310 # }}}
2311
2312 # {{{ debnet: setup network based on an existing one found on a partition
2313 config_debnet(){
2314 if checkbootparam 'debnet' ; then
2315  iszsh && setopt shwordsplit
2316  DEVICES="$(< /proc/partitions tail -n +3 | awk '{print "/dev/"$4}' | tr "\n" " ")"
2317  DEVICES="$DEVICES $(ls /dev/mapper/*)"
2318  FOUND_DEBNET=""
2319
2320  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
2321  eindent
2322  if ! mount | grep '/mnt ' 1>/dev/null 2>&1 ; then
2323     for i in $DEVICES; do
2324      if mount -o ro -t auto "$i" /mnt >/dev/null 2>&1; then
2325          einfo "Scanning on $i"
2326        if [ -f /mnt/etc/network/interfaces ]; then
2327          einfo "/etc/network/interfaces found on ${i}" ; eend 0
2328          FOUND_DEBNET="$i"
2329          break
2330        fi
2331        umount /mnt
2332      fi
2333     done
2334
2335    if [ -n "$FOUND_DEBNET" ]; then
2336      einfo "Stopping network."
2337        pump -k 1>/dev/null 2>&1
2338        /etc/init.d/networking stop 1>/dev/null 2>&1 ; eend $?
2339      einfo "Copying Debian network configuration from $FOUND_DEBNET to running system."
2340        rm -rf /etc/network/run
2341        cp -a /mnt/etc/network /etc
2342        rm -rf /etc/network/run
2343        mkdir /etc/network/run
2344        umount /mnt ; eend $?
2345      einfo "Starting network."
2346        invoke-rc.d networking start ; eend $?
2347    else
2348      eerror "/etc/network/interfaces not found." ; eend 1
2349    fi
2350    eoutdent
2351  else
2352   eerror "Error: /mnt already mounted." ; eend 1
2353  fi
2354 fi
2355 }
2356 # }}}
2357
2358 # {{{ check for broken ipw3945 driver which causes problems (especially on hd install)
2359 config_ipw3945() {
2360   if grep -q ipw3945 /proc/modules ; then
2361      if ! iwconfig 2>/dev/null| grep -qe 'IEEE 802' -qe 'unassociated' ; then
2362         ewarn "Broken ipw3945 network interface found, reloading module."
2363         rmmod ipw3945
2364         modprobe ipw3945
2365         eend $?
2366      fi
2367   fi
2368 }
2369 # }}}
2370
2371 # {{{ disable console blanking
2372 config_blanking(){
2373 if checkbootparam 'noblank' ; then
2374   einfo "Bootoption noblank found. Disabling monitor blanking."
2375   setterm -blank 0 ; eend $?
2376 fi
2377 }
2378 # }}}
2379
2380 # {{{ tohd= bootoption
2381 config_tohd()
2382 {
2383   if checkbootparam 'tohd' ; then
2384      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
2385      if [ -z "$TARGET" ] ; then
2386         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
2387         eerror "Please use something like tohd=/dev/sda9." ; eend 1
2388         return 1
2389      fi
2390
2391      if ! [ -b "$TARGET" ] ; then
2392         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
2393         return 1
2394      fi
2395
2396      if grep -q $TARGET /proc/mounts ; then
2397         eerror "$TARGET already mounted, skipping execution of tohd therefore."
2398         eend 1
2399         return 1
2400      fi
2401
2402      local MOUNTDIR=$(mktemp -d)
2403
2404      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
2405         einfo "Copyring live system to $TARGET - this might take a while"
2406         rsync -a --progress /live/image/live $MOUNTDIR
2407         sync
2408         umount "$MOUNTDIR"
2409         eend $?
2410         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
2411      else
2412         eerror "Error when trying to mount $TARGET, sorry."; eend 1
2413         return 1
2414      fi
2415
2416      rmdir "$MOUNTDIR"
2417   fi
2418 }
2419 # }}}
2420
2421 # {{{ grml2hd: automatic installation
2422 config_grml2hd(){
2423
2424 if checkbootparam "BOOT_IMAGE=grml2hd" ; then
2425
2426 if checkbootparam 'user' ; then
2427    NEWUSER=''
2428    NEWUSER="$(getbootparam 'user' 2>>$DEBUG)"
2429    sed -i "s/^NEWUSER=.*/NEWUSER=$NEWUSER/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2430 fi
2431
2432 if checkbootparam 'filesystem' ; then
2433    FILESYSTEM=''
2434    FILESYSTEM="$(getbootparam 'filesystem' 2>>$DEBUG)"
2435    sed -i "s/^FILESYSTEM=.*/FILESYSTEM=$FILESYSTEM/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2436 fi
2437
2438 if checkbootparam 'partition' ; then
2439    PARTITION=''
2440    PARTITION="$(getbootparam 'partition' 2>>$DEBUG)"
2441    # notice: the following checks whether the given partition is available, if not the skip
2442    # execution of grml2hd as it might result in data loss...
2443    if [ -r $PARTITION ] ; then
2444       sed -i "s#^PARTITION=.*#PARTITION=$PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2445    else
2446       ewarn "Partition $PARTITION does not exist. Skipping execution of grml2hd therefore." ; eend 1
2447    fi
2448 fi
2449
2450 if checkbootparam 'mbr' ; then
2451    BOOT_PARTITION=''
2452    BOOT_PARTITION="$(getbootparam 'mbr' 2>>$DEBUG)"
2453    sed -i "s#^BOOT_PARTITION=.*#BOOT_PARTITION=$BOOT_PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2454 fi
2455
2456 cat>|/usr/bin/grml2hd_noninteractive<<EOF
2457 #!/bin/sh
2458 GRML2HD_NONINTERACTIVE='yes' grml2hd
2459 EOF
2460
2461 chmod 755 /usr/bin/grml2hd_noninteractive
2462 einfo "Bootoption grml2hd found. Running automatic installation via grml2hd using /etc/grml2hd/config." && eend 0
2463 if [ -z "$GRML2HD_FAIL" ] ; then
2464    screen /usr/bin/grml2hd_noninteractive ; einfo "Invoking a shell, just exit to continue booting..." ; /bin/zsh
2465 else
2466    ewarn "There was an error adjusting /etc/grml2hd/config. Skipping execution of grml2hd for security reasons." ; eend 1
2467 fi
2468
2469 fi # if checkbootparam "BOOT_IMAGE=grml2hd ...
2470 }
2471 # }}}
2472
2473 # {{{ debootstrap: automatic installation
2474 config_debootstrap(){
2475
2476 if checkbootparam "BOOT_IMAGE=debian2hd" ; then
2477
2478 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
2479
2480 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
2481    eindent
2482    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
2483    eoutdent
2484    exit 1
2485 fi
2486
2487 if checkbootparam 'target' ; then
2488   TARGET=''
2489   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
2490   # notice: the following checks whether the given partition is available, if not the skip
2491   # execution of grml-debootstrap as it might result in data loss...
2492   if ! [ -r "$TARGET" ] ; then
2493      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
2494   fi
2495 else
2496   eindent
2497   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
2498   eoutdent
2499   exit 1
2500 fi
2501
2502 if checkbootparam 'grub' ; then
2503   GRUB=''
2504   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2505 fi
2506
2507 if checkbootparam 'groot' ; then
2508   GROOT=''
2509   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2510 fi
2511
2512 if checkbootparam 'release' ; then
2513   RELEASE=''
2514   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2515 fi
2516
2517 if checkbootparam 'mirror' ; then
2518   MIRROR=''
2519   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2520 fi
2521
2522 if checkbootparam 'boot_append' ; then
2523   BOOT_APPEND=''
2524   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2525 fi
2526
2527 if checkbootparam 'password' ; then
2528   PASSWORD=''
2529   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2530 fi
2531
2532 # now check which options are available
2533 if [ -n "TARGET" ] ; then
2534    TARGETCMD="--target $TARGET"
2535 else
2536    TARGETCMD=''
2537    eindent
2538    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2539    eoutdent
2540    exit 1
2541 fi
2542 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2543 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2544 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2545 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2546 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2547 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2548
2549 # and finally write script and execute it
2550 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2551 #!/bin/sh
2552 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2553 EOF
2554
2555 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2556
2557 screen /usr/bin/grml-debootstrap_noninteractive
2558 einfo "Invoking a shell, just exit to continue booting..."
2559 /bin/zsh
2560
2561 fi # checkbootparam "BOOT_IMAGE=debian2hd
2562 }
2563 # }}}
2564
2565 # {{{ Support customization
2566 config_distri(){
2567 if checkbootparam 'distri'; then
2568   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2569   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2570      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2571      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2572      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2573      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2574   fi
2575 fi
2576 }
2577 # }}}
2578
2579 ### {{{ backwards compatible stuff
2580 config_environment(){
2581   ewarn "config_environment is deprecated. Please set CONFIG_ENVIRONMENT in /etc/grml/autoconfig to 'no'." ; eend 0
2582 }
2583 config_keyboard(){
2584   ewarn "config_keyboard is deprecated. Please set CONFIG_KEYBOARD in /etc/grml/autoconfig to 'no'." ; eend 0
2585 }
2586 # }}}
2587
2588 ## END OF FILE #################################################################
2589 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3