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