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