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