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