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