8097a2d38b1751b97f3a6eb4c7c865360eb66230
[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     else
1962       DCSDIR="/live/image"
1963     fi
1964   fi
1965 fi
1966
1967 if [ -n "$DCSDIR" ]; then
1968   einfo "Debs, config, scripts will be read from $DCSDIR." ; eend 0
1969 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1970   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1971 fi
1972 }
1973
1974
1975 config_partconf() {
1976 if checkbootparam 'partconf' ; then
1977  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1978  if [ -n "$MOUNTDEVICE" ]; then
1979    [ -d /mnt/grml ] || mkdir /mnt/grml
1980    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1981     if [[ $RC == 0 ]]; then
1982       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1983       einfo "Copying files from $MOUNTDEVICE over grml system."
1984       for file in `cat /etc/grml/partconf` ; do
1985         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1986         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1987       done && eend 0
1988     else
1989       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1990     fi # mount $MOUNTDEVICE
1991    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1992  else
1993    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1994  fi # [ -n "$MOUNTDEVICE" ]
1995 fi
1996 }
1997 # }}}
1998
1999 # {{{ /cdrom/.*-options
2000 config_debs(){
2001 if checkbootparam 'debs' ; then
2002    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
2003    if ! echo $DEBS | grep -q '/'; then
2004      # backwards compatibility: if no path is given get debs from debs/
2005      DEBS="debs/$DEBS"
2006    fi
2007    einfo "Tring to install debian package(s) ${DEBS}"
2008    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
2009    dpkg -i $DEBS ; eend $?
2010 fi
2011 }
2012
2013 config_scripts(){
2014 if checkbootparam 'scripts' ; then
2015    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
2016    if [ -z "$SCRIPTS" ]; then
2017      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
2018    fi
2019    if ! echo $SCRIPTS | grep -q '/'; then
2020      # backwards compatibility: if no path is given get scripts from scripts/
2021      SCRIPTS="scripts/$SCRIPTS"
2022    fi
2023    SCRIPTS="${DCSDIR}/$SCRIPTS"
2024    if [ -d "$SCRIPTS" ]; then
2025      einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
2026      run-parts $SCRIPTS
2027    else
2028      einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
2029      sh -c $SCRIPTS
2030    fi
2031 fi
2032 }
2033
2034 config_config(){
2035 if checkbootparam 'config' ; then
2036   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
2037   if [ -z "$CONFIG" ]; then
2038     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
2039   fi
2040   if [ -n "$CONFIG" ]; then
2041     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
2042       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
2043
2044       cp -a ${DCSDIR}/${CONFIG}/* /
2045     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
2046       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
2047
2048       cd /
2049       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
2050     else
2051       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
2052     fi
2053   fi
2054 fi
2055 # umount /mnt/grml if it was mounted by finddcsdir
2056 # this doesn't really belong here
2057 grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
2058 }
2059 # }}}
2060
2061 # {{{ mypath
2062 config_mypath(){
2063 if checkbootparam 'mypath' ; then
2064    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
2065    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
2066    touch /etc/grml/my_path
2067    chmod 644 /etc/grml/my_path
2068    # make sure the directories exist:
2069    eindent
2070    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
2071        if ! [ -d "$i" ] ; then
2072           einfo "Creating directory $i"
2073           mkdir -p "$i" ; eend $?
2074        fi
2075    done
2076    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
2077    eoutdent
2078 fi
2079 }
2080 # }}}
2081
2082 # {{{ distcc
2083 config_distcc(){
2084 if checkbootparam 'distcc' ; then
2085  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
2086  if [ -n "$OPTIONS" ]; then
2087     NET=""
2088     INTERFACE=""
2089     if [ -n "$OPTIONS" ]; then
2090       NET="${OPTIONS%%,*}"
2091       R="${OPTIONS#*,}"
2092       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2093         OPTIONS="$R"
2094         INTERFACE="${OPTIONS%%,*}"
2095         R="${OPTIONS#*,}"
2096       fi
2097     fi
2098  fi
2099  CONFIG=/etc/default/distcc
2100  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
2101  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
2102
2103  if [ -n "$INTERFACE" ] ; then
2104    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2105
2106    counter=10
2107    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
2108      counter=$(( counter-1 ))
2109      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
2110      sleep 3
2111      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2112    done
2113  fi
2114
2115  if [ -n "$IP" ] ; then
2116    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
2117
2118    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
2119    eindent
2120     id distccd >/dev/null 2>&1 || \
2121     (
2122       einfo "Creating distcc user" ; \
2123       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
2124     )
2125
2126     einfo "Starting distcc for network ${NET}, listening on ${IP}."
2127    /etc/init.d/distcc start 1>/dev/null ; eend $?
2128    eoutdent
2129  else
2130    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
2131  fi
2132 fi
2133
2134 if checkbootparam 'gcc'; then
2135  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
2136  eindent
2137  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
2138  eoutdent
2139  rm -f /usr/bin/gcc
2140  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
2141 fi
2142
2143 if checkbootparam 'gpp'; then
2144  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
2145  eindent
2146   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
2147   if [ -x /usr/bin/g++-${GPP} ] ; then
2148      rm -f /usr/bin/g++
2149      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
2150   fi
2151   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
2152   if [ -x /usr/bin/cpp-${GPP} ] ; then
2153      rm -f /usr/bin/cpp
2154      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
2155   fi
2156  eoutdent
2157 fi
2158
2159 }
2160 # }}}
2161
2162 # {{{ load modules
2163 # Notice: use it only on live-cd system, if running from harddisk please
2164 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
2165 # in /etc/runlevel.conf
2166 config_modules(){
2167 MODULES_FILE=/etc/grml/modules
2168 if checkbootparam 'nomodules' ; then
2169   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
2170 elif [ -z "$INSTALLED" ]; then
2171  if [ -r $MODULES_FILE ] ; then
2172   einfo "Loading modules specified in ${MODULES_FILE}:"
2173   eindent
2174   grep '^[^#]' $MODULES_FILE | \
2175   while read module args; do
2176     [ "$module" ] || continue
2177       einfo "${module}"
2178       modprobe $module $args ; eend $?
2179   done
2180   eoutdent
2181  else
2182   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
2183  fi
2184 fi
2185 }
2186 # }}}
2187
2188 # {{{ 915resolution
2189 config_915resolution(){
2190 if checkbootparam '915resolution' ; then
2191  OPTIONS="$(getbootparam '915resolution' 2>>$DEBUG)"
2192   if [ -x /usr/sbin/915resolution ]; then
2193     CMD=915resolution
2194     MODE=""
2195     XRESO=""
2196     YRESO=""
2197     if [ -n "$OPTIONS" ]; then
2198       # Extra options
2199       MODE="${OPTIONS%%,*}"
2200       R="${OPTIONS#*,}"
2201       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2202         OPTIONS="$R"
2203         XRESO="${OPTIONS%%,*}"
2204         R="${OPTIONS#*,}"
2205         if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2206           OPTIONS="$R"
2207           YRESO="${OPTIONS%%,*}"
2208           R="${OPTIONS#*,}"
2209         fi
2210       fi
2211     fi
2212     einfo "Running 915resolution with options ${MODE} ${XRESO} ${YRESO}."
2213     [ -n "$MODE" ] && [ -n "$XRESO"  ] && [ -n "$YRESO" ]  && ( sh -c "$CMD $MODE $XRESO $YRESO" & )
2214     eend 0
2215   fi
2216 fi
2217 }
2218 # }}}
2219
2220 # {{{ SW-RAID
2221 config_swraid(){
2222   if [ -z "$INSTALLED" ] ; then
2223   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
2224   if checkbootparam 'noraid'   || checkbootparam 'noswraid' -o \
2225      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
2226      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
2227   else
2228     if ! [ -x /sbin/mdadm ] ; then
2229        eerror "mdadm not available, can not execute it." ; eend 1
2230     else
2231
2232        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2233        # find out whether we have a valid configuration file already
2234        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2235           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
2236           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
2237           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
2238         else
2239           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
2240        fi
2241
2242        if ! checkbootparam 'swraid' ; then
2243           eindent
2244           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
2245           eoutdent
2246        else
2247           einfo "Bootoption swraid found. Searching for software RAID arrays:"
2248           eindent
2249            IFSOLD=${IFS:-}
2250            IFS='
2251 '
2252            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
2253                case $line in
2254                  *'No arrays found'*)
2255                    ewarn "$line" ; eend 0
2256                    ;;
2257                  *)
2258                    einfo "$line" ; eend 0
2259                    ;;
2260                esac
2261            done
2262            IFS=$IFSOLD
2263          eoutdent
2264
2265          if [ -r /proc/mdstat ] ; then
2266             eindent
2267             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
2268             if [ -z "$MDSTAT" ] ; then
2269                ewarn "No active arrays found" ; eend 0
2270             else
2271                IFSOLD=${IFS:-}
2272                IFS='
2273 '
2274                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
2275                    einfo "active arrays: $line" ; eend 0
2276                done
2277                IFS=$IFSOLD
2278             fi
2279             eoutdent
2280          fi # /proc/mdstat
2281        fi # bootoption swraid
2282
2283      fi # is /sbin/mdadm executable?
2284   fi # check for bootoptions
2285   fi # run only in live-cd mode
2286 }
2287 # }}}
2288
2289 # {{{ LVM (Logical Volumes)
2290 config_lvm(){
2291   if [ -z "$INSTALLED" ] ; then
2292   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
2293   if checkbootparam 'nolvm' ; then
2294      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
2295   else
2296     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
2297     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
2298        eerror "LVM not available, can not execute it." ; eend 1
2299     else
2300        if lvdisplay 2>&1 | grep -v 'No volume groups found' 1>/dev/null 2>&1 ; then
2301           einfo "You seem to have logical volumes (LVM) on your system."
2302           eindent
2303           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
2304           eend 0
2305           if checkbootparam 'lvm' ; then
2306              einfo "Bootoption LVM found. Searching for logical volumes:"
2307              /etc/init.d/lvm2 start ; eend $?
2308           fi
2309           eoutdent
2310        fi
2311     fi # check for lvm binary
2312   fi # check for bootoption nolvm
2313   fi # run only in live-cd mode
2314 }
2315 # }}}
2316
2317 # {{{ debnet: setup network based on an existing one found on a partition
2318 config_debnet(){
2319 if checkbootparam 'debnet' ; then
2320  iszsh && setopt shwordsplit
2321  DEVICES="$(< /proc/partitions tail -n +3 | awk '{print "/dev/"$4}' | tr "\n" " ")"
2322  DEVICES="$DEVICES $(ls /dev/mapper/*)"
2323  FOUND_DEBNET=""
2324
2325  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
2326  eindent
2327  if ! mount | grep '/mnt ' 1>/dev/null 2>&1 ; then
2328     for i in $DEVICES; do
2329      if mount -o ro -t auto "$i" /mnt >/dev/null 2>&1; then
2330          einfo "Scanning on $i"
2331        if [ -f /mnt/etc/network/interfaces ]; then
2332          einfo "/etc/network/interfaces found on ${i}" ; eend 0
2333          FOUND_DEBNET="$i"
2334          break
2335        fi
2336        umount /mnt
2337      fi
2338     done
2339
2340    if [ -n "$FOUND_DEBNET" ]; then
2341      einfo "Stopping network."
2342        pump -k 1>/dev/null 2>&1
2343        /etc/init.d/networking stop 1>/dev/null 2>&1 ; eend $?
2344      einfo "Copying Debian network configuration from $FOUND_DEBNET to running system."
2345        rm -rf /etc/network/run
2346        cp -a /mnt/etc/network /etc
2347        rm -rf /etc/network/run
2348        mkdir /etc/network/run
2349        umount /mnt ; eend $?
2350      einfo "Starting network."
2351        invoke-rc.d networking start ; eend $?
2352    else
2353      eerror "/etc/network/interfaces not found." ; eend 1
2354    fi
2355    eoutdent
2356  else
2357   eerror "Error: /mnt already mounted." ; eend 1
2358  fi
2359 fi
2360 }
2361 # }}}
2362
2363 # {{{ check for broken ipw3945 driver which causes problems (especially on hd install)
2364 config_ipw3945() {
2365   if grep -q ipw3945 /proc/modules ; then
2366      if ! iwconfig 2>/dev/null| grep -qe 'IEEE 802' -qe 'unassociated' ; then
2367         ewarn "Broken ipw3945 network interface found, reloading module."
2368         rmmod ipw3945
2369         modprobe ipw3945
2370         eend $?
2371      fi
2372   fi
2373 }
2374 # }}}
2375
2376 # {{{ disable console blanking
2377 config_blanking(){
2378 if checkbootparam 'noblank' ; then
2379   einfo "Bootoption noblank found. Disabling monitor blanking."
2380   setterm -blank 0 ; eend $?
2381 fi
2382 }
2383 # }}}
2384
2385 # {{{ tohd= bootoption
2386 config_tohd()
2387 {
2388   if checkbootparam 'tohd' ; then
2389      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
2390      if [ -z "$TARGET" ] ; then
2391         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
2392         eerror "Please use something like tohd=/dev/sda9." ; eend 1
2393         return 1
2394      fi
2395
2396      if ! [ -b "$TARGET" ] ; then
2397         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
2398         return 1
2399      fi
2400
2401      if grep -q $TARGET /proc/mounts ; then
2402         eerror "$TARGET already mounted, skipping execution of tohd therefore."
2403         eend 1
2404         return 1
2405      fi
2406
2407      local MOUNTDIR=$(mktemp -d)
2408
2409      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
2410         einfo "Copyring live system to $TARGET - this might take a while"
2411         rsync -a --progress /live/image/live $MOUNTDIR
2412         sync
2413         umount "$MOUNTDIR"
2414         eend $?
2415         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
2416      else
2417         eerror "Error when trying to mount $TARGET, sorry."; eend 1
2418         return 1
2419      fi
2420
2421      rmdir "$MOUNTDIR"
2422   fi
2423 }
2424 # }}}
2425
2426 # {{{ grml2hd: automatic installation
2427 config_grml2hd(){
2428
2429 if checkbootparam "BOOT_IMAGE=grml2hd" ; then
2430
2431 if checkbootparam 'user' ; then
2432    NEWUSER=''
2433    NEWUSER="$(getbootparam 'user' 2>>$DEBUG)"
2434    sed -i "s/^NEWUSER=.*/NEWUSER=$NEWUSER/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2435 fi
2436
2437 if checkbootparam 'filesystem' ; then
2438    FILESYSTEM=''
2439    FILESYSTEM="$(getbootparam 'filesystem' 2>>$DEBUG)"
2440    sed -i "s/^FILESYSTEM=.*/FILESYSTEM=$FILESYSTEM/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2441 fi
2442
2443 if checkbootparam 'partition' ; then
2444    PARTITION=''
2445    PARTITION="$(getbootparam 'partition' 2>>$DEBUG)"
2446    # notice: the following checks whether the given partition is available, if not the skip
2447    # execution of grml2hd as it might result in data loss...
2448    if [ -r $PARTITION ] ; then
2449       sed -i "s#^PARTITION=.*#PARTITION=$PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2450    else
2451       ewarn "Partition $PARTITION does not exist. Skipping execution of grml2hd therefore." ; eend 1
2452    fi
2453 fi
2454
2455 if checkbootparam 'mbr' ; then
2456    BOOT_PARTITION=''
2457    BOOT_PARTITION="$(getbootparam 'mbr' 2>>$DEBUG)"
2458    sed -i "s#^BOOT_PARTITION=.*#BOOT_PARTITION=$BOOT_PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2459 fi
2460
2461 cat>|/usr/bin/grml2hd_noninteractive<<EOF
2462 #!/bin/sh
2463 GRML2HD_NONINTERACTIVE='yes' grml2hd
2464 EOF
2465
2466 chmod 755 /usr/bin/grml2hd_noninteractive
2467 einfo "Bootoption grml2hd found. Running automatic installation via grml2hd using /etc/grml2hd/config." && eend 0
2468 if [ -z "$GRML2HD_FAIL" ] ; then
2469    screen /usr/bin/grml2hd_noninteractive ; einfo "Invoking a shell, just exit to continue booting..." ; /bin/zsh
2470 else
2471    ewarn "There was an error adjusting /etc/grml2hd/config. Skipping execution of grml2hd for security reasons." ; eend 1
2472 fi
2473
2474 fi # if checkbootparam "BOOT_IMAGE=grml2hd ...
2475 }
2476 # }}}
2477
2478 # {{{ debootstrap: automatic installation
2479 config_debootstrap(){
2480
2481 if checkbootparam "BOOT_IMAGE=debian2hd" ; then
2482
2483 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
2484
2485 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
2486    eindent
2487    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
2488    eoutdent
2489    exit 1
2490 fi
2491
2492 if checkbootparam 'target' ; then
2493   TARGET=''
2494   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
2495   # notice: the following checks whether the given partition is available, if not the skip
2496   # execution of grml-debootstrap as it might result in data loss...
2497   if ! [ -r "$TARGET" ] ; then
2498      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
2499   fi
2500 else
2501   eindent
2502   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
2503   eoutdent
2504   exit 1
2505 fi
2506
2507 if checkbootparam 'grub' ; then
2508   GRUB=''
2509   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2510 fi
2511
2512 if checkbootparam 'groot' ; then
2513   GROOT=''
2514   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2515 fi
2516
2517 if checkbootparam 'release' ; then
2518   RELEASE=''
2519   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2520 fi
2521
2522 if checkbootparam 'mirror' ; then
2523   MIRROR=''
2524   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2525 fi
2526
2527 if checkbootparam 'boot_append' ; then
2528   BOOT_APPEND=''
2529   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2530 fi
2531
2532 if checkbootparam 'password' ; then
2533   PASSWORD=''
2534   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2535 fi
2536
2537 # now check which options are available
2538 if [ -n "TARGET" ] ; then
2539    TARGETCMD="--target $TARGET"
2540 else
2541    TARGETCMD=''
2542    eindent
2543    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2544    eoutdent
2545    exit 1
2546 fi
2547 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2548 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2549 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2550 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2551 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2552 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2553
2554 # and finally write script and execute it
2555 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2556 #!/bin/sh
2557 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2558 EOF
2559
2560 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2561
2562 screen /usr/bin/grml-debootstrap_noninteractive
2563 einfo "Invoking a shell, just exit to continue booting..."
2564 /bin/zsh
2565
2566 fi # checkbootparam "BOOT_IMAGE=debian2hd
2567 }
2568 # }}}
2569
2570 # {{{ Support customization
2571 config_distri(){
2572 if checkbootparam 'distri'; then
2573   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2574   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2575      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2576      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2577      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2578      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2579   fi
2580 fi
2581 }
2582 # }}}
2583
2584 ### {{{ backwards compatible stuff
2585 config_environment(){
2586   ewarn "config_environment is deprecated. Please set CONFIG_ENVIRONMENT in /etc/grml/autoconfig to 'no'." ; eend 0
2587 }
2588 config_keyboard(){
2589   ewarn "config_keyboard is deprecated. Please set CONFIG_KEYBOARD in /etc/grml/autoconfig to 'no'." ; eend 0
2590 }
2591 # }}}
2592
2593 ## END OF FILE #################################################################
2594 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3