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