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