c9e4ff54bff7b685391e88ed1468141258ffc76f
[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 >>$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 config_mixer(){
1601 if ! [ -x /usr/bin/aumix ] ; then
1602   eerror "aumix binary not available. Can not set sound volumes therefore." ; eend 1
1603 else
1604
1605   if ! [ -r /proc/asound/cards ] ; then
1606      ewarn "No soundcard present, skipping mixer settings therefore." ; eend 0
1607      return
1608   fi
1609
1610   if checkbootparam 'vol' ; then
1611     VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1612     if [ -z "$VOL" ] ; then
1613       eerror "Bootoption vol found but no volume level/parameter given. Using defaults." ; eend 1
1614       VOL='75' # default
1615     fi
1616   else
1617     VOL='75' # default
1618   fi
1619
1620   if checkbootparam 'nosound' ; then
1621     einfo "Muting sound devices on request."
1622     # some IBM notebooks require the following stuff:
1623     if [ -x /usr/bin/amixer ] ; then
1624        if amixer get Front 1>/dev/null 2>>$DEBUG ; then
1625           amixer set Front unmute 1>/dev/null
1626           amixer set Front 0% 1>/dev/null
1627        fi
1628     fi
1629     ERROR=$(aumix -w 0 -v 0 -p 0 -m 0 2>&1) ; RC=$?
1630     if [ -n "$ERROR" ] ; then
1631        eindent
1632        eerror "Problem muting sound devices: $ERROR"
1633        eoutdent
1634     fi
1635     eend $RC
1636   elif [ -z "$INSTALLED" ]; then
1637       einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1638       # some IBM notebooks require the following stuff:
1639       if [ -x /usr/bin/amixer ] ; then
1640          if amixer get Front 1>/dev/null 2>>$DEBUG ; then
1641             amixer set Front unmute 1>/dev/null
1642             amixer set Front ${VOL}% 1>/dev/null
1643          fi
1644       fi
1645       # by default assume '0' as volume for microphone:
1646       if checkbootparam 'micvol' ; then
1647          MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1648       else
1649          MICVOL=0
1650       fi
1651
1652       # finally set the volumes:
1653       ERROR=$(aumix -w $VOL -v $VOL -p $VOL -m $MICVOL 2>&1) ; RC=$?
1654       if [ -n "$ERROR" ] ; then
1655          eindent
1656          eerror "Problem setting mixer volumes: $ERROR (no soundcard?)"
1657          eoutdent
1658       fi
1659       eend $RC
1660   fi
1661
1662 fi
1663 }
1664 # }}}
1665
1666 # {{{ modem detection
1667 config_modem(){
1668 if checkbootparam 'nomodem'; then
1669   ewarn "Skipping check for AC97 modem controller as requested on boot commandline." ; eend 0
1670 else
1671   if [ -x /etc/init.d/sl-modem-daemon ] ; then
1672      if lspci | grep Intel | grep -q "AC'97 Modem Controller" ; then
1673         einfo "AC97 modem controller detected. Start it running 'Start sl-modem-daemon'."
1674         eend 0
1675      fi
1676   fi
1677 fi
1678 }
1679 # }}}
1680
1681 # {{{ keyboard add-ons
1682 config_setkeycodes(){
1683 if checkbootparam 'setkeycodes' ; then
1684  einfo "Setting keycodes as requested via bootparameter 'setkeycodes'."
1685   # MS MM keyboard add-on
1686   # fix
1687   setkeycodes e001 126 &>/dev/null
1688   setkeycodes e059 127 &>/dev/null
1689   # fn keys
1690   setkeycodes e03b 59 &>/dev/null
1691   setkeycodes e008 60 &>/dev/null
1692   setkeycodes e007 61 &>/dev/null
1693   setkeycodes e03e 62 &>/dev/null
1694   setkeycodes e03f 63 &>/dev/null
1695   setkeycodes e040 64 &>/dev/null
1696   setkeycodes e041 65 &>/dev/null
1697   setkeycodes e042 66 &>/dev/null
1698   setkeycodes e043 67 &>/dev/null
1699   setkeycodes e023 68 &>/dev/null
1700   setkeycodes e057 87 &>/dev/null
1701   setkeycodes e058 88 &>/dev/null
1702   # hp keycodes
1703   setkeycodes e00a 89 e008 90 &>/dev/null
1704  eend 0
1705 fi
1706 }
1707 # }}}
1708
1709 # {{{ wondershaper
1710 config_wondershaper(){
1711  if checkbootparam 'wondershaper' ; then
1712     WONDER="$(getbootparam 'wondershaper' 2>>$DEBUG)"
1713     CMD=wondershaper
1714     DEVICE=""
1715     DOWNSTREAM=""
1716     UPSTREAM=""
1717     if [ -n "$WONDER" ]; then
1718       # Extra options
1719       DEVICE="${WONDER%%,*}"
1720       R="${WONDER#*,}"
1721       if [ -n "$R" -a "$R" != "$WONDER" ]; then
1722         WONDER="$R"
1723         DOWNSTREAM="${WONDER%%,*}"
1724         R="${WONDER#*,}"
1725         if [ -n "$R" -a "$R" != "$WONDER" ]; then
1726           WONDER="$R"
1727           UPSTREAM="${WONDER%%,*}"
1728           R="${WONDER#*,}"
1729         fi
1730       fi
1731     fi
1732     [ -n "$DEVICE" ]     && CMD="$CMD $DEVICE"
1733     [ -n "$DOWNSTREAM" ] && CMD="$CMD $DOWNSTREAM"
1734     [ -n "$UPSTREAM" ]   && CMD="$CMD $UPSTREAM"
1735     einfo "Starting wondershaper (${CMD}) in background."
1736     ( sh -c $CMD & ) && eend 0
1737  fi
1738 }
1739 # }}}
1740
1741 # {{{ syslog-ng
1742 config_syslog(){
1743  if checkbootparam 'nosyslog'; then
1744     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1745  else
1746     SYSLOGD=''
1747     [ -x /etc/init.d/syslog-ng ] && SYSLOGD='syslog-ng'
1748     [ -x /etc/init.d/rsyslog   ] && SYSLOGD='rsyslog'
1749     [ -x /etc/init.d/dsyslog   ] && SYSLOGD='dsyslog'
1750     [ -x /etc/init.d/sysklogd  ] && SYSLOGD='sysklogd'
1751     [ -x /etc/init.d/inetutils-syslogd ] && SYSLOGD='inetutils-syslogd'
1752
1753     if [ -z "$SYSLOGD" ] ; then
1754        eerror "No syslog daemon found." ; eend 1
1755     else
1756        einfo "Starting $SYSLOGD in background."
1757        /etc/init.d/$SYSLOGD start 1>>$DEBUG &
1758        eend 0
1759     fi
1760  fi
1761 }
1762 # }}}
1763
1764 # {{{ gpm
1765 config_gpm(){
1766  if checkbootparam 'nogpm'; then
1767   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1768  else
1769    if ! [ -r /dev/input/mice ] ; then
1770       eerror "No mouse found - not starting GPM." ; eend 1
1771    else
1772       einfo "Starting gpm in background."
1773       /etc/init.d/gpm start 1>>$DEBUG &
1774       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start 1>>$DEBUG ) &
1775       eend 0
1776    fi
1777  fi
1778 }
1779 # }}}
1780
1781 # {{{ services
1782 config_services(){
1783  if checkbootparam 'services' ; then
1784     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1785     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1786     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1787     einfo "Starting service(s) ${SERVICENL} in background."
1788     for service in $(echo -e $SERVICELIST) ; do
1789        /etc/init.d/${service} start 1>>$DEBUG &
1790     done
1791     [ "$?" == "0" ] ; eend $?
1792  fi
1793 }
1794 # }}}
1795
1796 # {{{ remote files
1797 get_remote_file() {
1798   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1799   SOURCE=$(eval echo "$1")
1800   TARGET="$2"
1801   getconfig() {
1802   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1803        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1804   }
1805   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1806   counter=10
1807   while ! getconfig && [[ "$counter" != 0 ]] ; do
1808     echo -n "Sleeping for 1 second and trying to get config again... "
1809     counter=$(( counter-1 ))
1810     echo "$counter tries left" ; sleep 1
1811   done
1812   if [ -s "$TARGET" ] ; then
1813     einfo "Downloading was successfull." ; eend 0
1814     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1815     md5sum ${TARGET} ; eend 0
1816     return 0;
1817   else
1818     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1819     return 1;
1820  fi
1821 }
1822 # }}}
1823
1824 # {{{ config files
1825 config_netconfig(){
1826  if checkbootparam 'netconfig' ; then
1827   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1828   CONFIGFILE='/tmp/netconfig.grml'
1829
1830   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1831     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1832   fi
1833
1834  fi
1835 }
1836 # }}}
1837
1838 # {{{ remote scripts
1839 config_netscript() {
1840  if checkbootparam 'netscript' ; then
1841   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1842   SCRIPTFILE='/tmp/netscript.grml'
1843
1844   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1845     chmod +x ${SCRIPTFILE}
1846     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && ${SCRIPTFILE} ; eend $?
1847   fi
1848
1849  fi
1850 }
1851 # }}}
1852
1853 # {{{ blindsound
1854 config_blindsound(){
1855  if checkbootparam 'blind' ; then
1856     beep
1857     flitewrapper "welcome to the gremel system"
1858  fi
1859 }
1860 # }}}
1861
1862 # {{{ welcome sound
1863 config_welcome(){
1864  if checkbootparam 'welcome' ; then
1865     flitewrapper "welcome to the gremel system"
1866  fi
1867 }
1868 # }}}
1869
1870 # {{{ fix/workaround for unionfs
1871 fix_unionfs(){
1872   if [ -z "$INSTALLED" ]; then
1873    touch /var/cache/apt/*cache.bin
1874   fi
1875 }
1876 # }}}
1877
1878 # {{{ create all /mnt-directories
1879 create_mnt_dirs(){
1880   ewarn "create_mnt_dirs is deprecated as grml-rebuildfstab does all we need."
1881   ewarn "Please set CONFIG_CREATE_MNT_DIRS='no' in /etc/grml/autoconfig" ; eend 0
1882 }
1883 # }}}
1884
1885 # {{{ start X window system via grml-x
1886 config_x_startup(){
1887 # make sure we start X only if startx is used *before* a nostartx option
1888 # so it's possible to disable automatic X startup using nostart
1889 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1890  if [ -x /usr/X11R6/bin/X ] ; then
1891   if [ -z "$INSTALLED" ] ; then
1892    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1893    if [ -z "$WINDOWMANAGER" ] ; then
1894      einfo "No window manager specified. Taking ${WHITE}wm-ng${NORMAL} as default." && eend 0
1895      WINDOWMANAGER="wm-ng"
1896    else
1897      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1898    fi
1899    einfo "Changing to runlevel 5 for starting grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1900    config_userfstab || fstabuser='grml'
1901  cat>|/etc/init.d/xstartup<<EOF
1902 #!/bin/sh
1903 # su - $fstabuser -c 'grml-x "$WINDOWMANAGER"'
1904 sudo -u $fstabuser -i /usr/bin/grml-x $WINDOWMANAGER 1>>$DEBUG
1905 EOF
1906    chmod 755 /etc/init.d/xstartup
1907
1908    # adjust inittab for xstartup
1909    if grep -q '^6:' /etc/inittab ; then
1910       sed -i 's|^6:.*|6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /bin/zsh"|' /etc/inittab
1911    else # just append tty6 to inittab if no definition is present:
1912       echo '6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /bin/zsh"' >> /etc/inittab
1913    fi
1914
1915    /sbin/telinit q ; eend $?
1916
1917    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1918       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1919    else
1920       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1921    fi
1922
1923   else
1924     eerror "We are not running in live mode - startx will not work, skipping it."
1925     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1926   fi
1927  else
1928    eerror "/usr/X11R6/bin/X is not present on this grml flavour."
1929    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1930  fi
1931 fi
1932 }
1933 # }}}
1934
1935 # {{{ configuration framework
1936 config_extract(){
1937 if checkbootparam 'extract' ; then
1938  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1939  EXTRACTOPTIONS="-- -x $EXTRACT"
1940 fi
1941 }
1942
1943 config_finddcsdir() {
1944 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1945 #    on the command line, nothing is changed and the dcs files are
1946 #    searched within the .iso, $dcs-dir is set to the root directory
1947 #    within the .iso
1948 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1949 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1950 #    set, $dcs-dir is set to the root directory within the .iso.
1951 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1952 #    foo, even if a GRMLCFG partition is present.
1953 DCSDIR=""
1954 if checkbootparam 'noautoconfig' || checkbootparam 'forensic' ; then
1955   ewarn "Skipping running automount of device(s) labeled GRMLCFG as requested." ; eend 0
1956 else
1957   if [ -z "$INSTALLED" ] ; then
1958     if checkbootparam 'myconfig' ; then
1959       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1960       if [ -z "$DCSDEVICE" ]; then
1961         einfo "No device for bootoption myconfig provided." ; eend 1
1962       fi # [ -z "$DCSDEVICE" ]
1963     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1964       einfo "Searching for device(s) labeled with GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1965       eindent
1966       # We do need the following fix so floppy disk is available to blkid in any case :-/
1967       if [ -r /dev/fd0 ] ; then
1968         einfo "Floppy device detected. Trying to access floppy disk."
1969         if timeout 4 dd if=/dev/fd0 of=/dev/null bs=512 count=1 1>>$DEBUG 2>&1 ; then
1970            blkid /dev/fd0 1>>$DEBUG 2>&1
1971         fi
1972       fi
1973       DCSDEVICE=$(blkid -t LABEL=GRMLCFG | head -1 | awk -F: '{print $1}')
1974     fi
1975     if [ -n "$DCSDEVICE" ]; then
1976       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1977       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1978       if [ -n "$DCSDIR" ]; then
1979         einfo "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1980       else
1981         [ -d /mnt/grml ] || mkdir /mnt/grml
1982         umount /mnt/grml 1>>$DEBUG 2>&1 # make sure it is not mounted
1983         mount -o ro -t auto $DCSDEVICE  /mnt/grml ; RC="$?"
1984         if [[ $RC == 0 ]]; then
1985           einfo "Successfully mounted $DCSDEVICE to /mnt/grml (readonly)." ; eend 0
1986           eindent
1987         fi
1988         DCSDIR="/mnt/grml"
1989       fi
1990     else
1991       DCSDIR="/live/image"
1992     fi
1993   fi
1994 fi
1995
1996 if [ -n "$DCSDIR" ]; then
1997   einfo "Debs, config, scripts will be read from $DCSDIR." ; eend 0
1998 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1999   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
2000 fi
2001 }
2002
2003
2004 config_partconf() {
2005 if checkbootparam 'partconf' ; then
2006  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
2007  if [ -n "$MOUNTDEVICE" ]; then
2008    [ -d /mnt/grml ] || mkdir /mnt/grml
2009    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
2010     if [[ $RC == 0 ]]; then
2011       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
2012       einfo "Copying files from $MOUNTDEVICE over grml system."
2013       for file in `cat /etc/grml/partconf` ; do
2014         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
2015         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
2016       done && eend 0
2017     else
2018       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
2019     fi # mount $MOUNTDEVICE
2020    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
2021  else
2022    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
2023  fi # [ -n "$MOUNTDEVICE" ]
2024 fi
2025 }
2026 # }}}
2027
2028 # {{{ /cdrom/.*-options
2029 config_debs(){
2030 if checkbootparam 'debs' ; then
2031    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
2032    if ! echo $DEBS | grep -q '/'; then
2033      # backwards compatibility: if no path is given get debs from debs/
2034      DEBS="debs/$DEBS"
2035    fi
2036    einfo "Tring to install debian package(s) ${DEBS}"
2037    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
2038    dpkg -i $DEBS ; eend $?
2039 fi
2040 }
2041
2042 config_scripts(){
2043 if checkbootparam 'scripts' ; then
2044    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
2045    if [ -z "$SCRIPTS" ]; then
2046      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
2047    fi
2048    if ! echo $SCRIPTS | grep -q '/'; then
2049      # backwards compatibility: if no path is given get scripts from scripts/
2050      SCRIPTS="scripts/$SCRIPTS"
2051    fi
2052    SCRIPTS="${DCSDIR}/$SCRIPTS"
2053    if [ -d "$SCRIPTS" ]; then
2054      einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
2055      run-parts $SCRIPTS
2056    else
2057      einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
2058      sh -c $SCRIPTS
2059    fi
2060 fi
2061 }
2062
2063 config_config(){
2064 if checkbootparam 'config' ; then
2065   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
2066   if [ -z "$CONFIG" ]; then
2067     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
2068   fi
2069   if [ -n "$CONFIG" ]; then
2070     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
2071       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
2072
2073       cp -a ${DCSDIR}/${CONFIG}/* /
2074     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
2075       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
2076
2077       cd /
2078       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
2079     else
2080       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
2081     fi
2082   fi
2083 fi
2084 # umount /mnt/grml if it was mounted by finddcsdir
2085 # this doesn't really belong here
2086 grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
2087 }
2088 # }}}
2089
2090 # {{{ mypath
2091 config_mypath(){
2092 if checkbootparam 'mypath' ; then
2093    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
2094    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
2095    touch /etc/grml/my_path
2096    chmod 644 /etc/grml/my_path
2097    # make sure the directories exist:
2098    eindent
2099    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
2100        if ! [ -d "$i" ] ; then
2101           einfo "Creating directory $i"
2102           mkdir -p "$i" ; eend $?
2103        fi
2104    done
2105    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
2106    eoutdent
2107 fi
2108 }
2109 # }}}
2110
2111 # {{{ distcc
2112 config_distcc(){
2113 if checkbootparam 'distcc' ; then
2114  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
2115  if [ -n "$OPTIONS" ]; then
2116     NET=""
2117     INTERFACE=""
2118     if [ -n "$OPTIONS" ]; then
2119       NET="${OPTIONS%%,*}"
2120       R="${OPTIONS#*,}"
2121       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2122         OPTIONS="$R"
2123         INTERFACE="${OPTIONS%%,*}"
2124         R="${OPTIONS#*,}"
2125       fi
2126     fi
2127  fi
2128  CONFIG=/etc/default/distcc
2129  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
2130  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
2131
2132  if [ -n "$INTERFACE" ] ; then
2133    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2134
2135    counter=10
2136    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
2137      counter=$(( counter-1 ))
2138      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
2139      sleep 3
2140      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2141    done
2142  fi
2143
2144  if [ -n "$IP" ] ; then
2145    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
2146
2147    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
2148    eindent
2149     id distccd >/dev/null 2>&1 || \
2150     (
2151       einfo "Creating distcc user" ; \
2152       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
2153     )
2154
2155     einfo "Starting distcc for network ${NET}, listening on ${IP}."
2156    /etc/init.d/distcc start 1>/dev/null ; eend $?
2157    eoutdent
2158  else
2159    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
2160  fi
2161 fi
2162
2163 if checkbootparam 'gcc'; then
2164  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
2165  eindent
2166  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
2167  eoutdent
2168  rm -f /usr/bin/gcc
2169  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
2170 fi
2171
2172 if checkbootparam 'gpp'; then
2173  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
2174  eindent
2175   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
2176   if [ -x /usr/bin/g++-${GPP} ] ; then
2177      rm -f /usr/bin/g++
2178      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
2179   fi
2180   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
2181   if [ -x /usr/bin/cpp-${GPP} ] ; then
2182      rm -f /usr/bin/cpp
2183      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
2184   fi
2185  eoutdent
2186 fi
2187
2188 }
2189 # }}}
2190
2191 # {{{ load modules
2192 # Notice: use it only on live-cd system, if running from harddisk please
2193 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
2194 # in /etc/runlevel.conf
2195 config_modules(){
2196 MODULES_FILE=/etc/grml/modules
2197 if checkbootparam 'nomodules' ; then
2198   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
2199 elif [ -z "$INSTALLED" ]; then
2200  if [ -r $MODULES_FILE ] ; then
2201   einfo "Loading modules specified in ${MODULES_FILE}:"
2202   eindent
2203   grep '^[^#]' $MODULES_FILE | \
2204   while read module args; do
2205     [ "$module" ] || continue
2206       einfo "${module}"
2207       modprobe $module $args ; eend $?
2208   done
2209   eoutdent
2210  else
2211   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
2212  fi
2213 fi
2214 }
2215 # }}}
2216
2217 # {{{ 915resolution
2218 config_915resolution(){
2219 if checkbootparam '915resolution' ; then
2220  OPTIONS="$(getbootparam '915resolution' 2>>$DEBUG)"
2221   if [ -x /usr/sbin/915resolution ]; then
2222     CMD=915resolution
2223     MODE=""
2224     XRESO=""
2225     YRESO=""
2226     if [ -n "$OPTIONS" ]; then
2227       # Extra options
2228       MODE="${OPTIONS%%,*}"
2229       R="${OPTIONS#*,}"
2230       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2231         OPTIONS="$R"
2232         XRESO="${OPTIONS%%,*}"
2233         R="${OPTIONS#*,}"
2234         if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2235           OPTIONS="$R"
2236           YRESO="${OPTIONS%%,*}"
2237           R="${OPTIONS#*,}"
2238         fi
2239       fi
2240     fi
2241     einfo "Running 915resolution with options ${MODE} ${XRESO} ${YRESO}."
2242     [ -n "$MODE" ] && [ -n "$XRESO"  ] && [ -n "$YRESO" ]  && ( sh -c "$CMD $MODE $XRESO $YRESO" & )
2243     eend 0
2244   fi
2245 fi
2246 }
2247 # }}}
2248
2249 # {{{ SW-RAID
2250 config_swraid(){
2251   if [ -z "$INSTALLED" ] ; then
2252   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
2253   if checkbootparam 'noraid'   || checkbootparam 'noswraid' -o \
2254      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
2255      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
2256   else
2257     if ! [ -x /sbin/mdadm ] ; then
2258        eerror "mdadm not available, can not execute it." ; eend 1
2259     else
2260
2261        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2262        # find out whether we have a valid configuration file already
2263        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2264           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
2265           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
2266           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
2267         else
2268           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
2269        fi
2270
2271        if ! checkbootparam 'swraid' ; then
2272           eindent
2273           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
2274           eoutdent
2275        else
2276           einfo "Bootoption swraid found. Searching for software RAID arrays:"
2277           eindent
2278            IFSOLD=${IFS:-}
2279            IFS='
2280 '
2281            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
2282                case $line in
2283                  *'No arrays found'*)
2284                    ewarn "$line" ; eend 0
2285                    ;;
2286                  *)
2287                    einfo "$line" ; eend 0
2288                    ;;
2289                esac
2290            done
2291            IFS=$IFSOLD
2292          eoutdent
2293
2294          if [ -r /proc/mdstat ] ; then
2295             eindent
2296             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
2297             if [ -z "$MDSTAT" ] ; then
2298                ewarn "No active arrays found" ; eend 0
2299             else
2300                IFSOLD=${IFS:-}
2301                IFS='
2302 '
2303                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
2304                    einfo "active arrays: $line" ; eend 0
2305                done
2306                IFS=$IFSOLD
2307             fi
2308             eoutdent
2309          fi # /proc/mdstat
2310        fi # bootoption swraid
2311
2312      fi # is /sbin/mdadm executable?
2313   fi # check for bootoptions
2314   fi # run only in live-cd mode
2315 }
2316 # }}}
2317
2318 # {{{ LVM (Logical Volumes)
2319 config_lvm(){
2320   if [ -z "$INSTALLED" ] ; then
2321   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
2322   if checkbootparam 'nolvm' ; then
2323      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
2324   else
2325     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
2326     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
2327        eerror "LVM not available, can not execute it." ; eend 1
2328     else
2329        if lvdisplay 2>&1 | grep -v 'No volume groups found' 1>/dev/null 2>&1 ; then
2330           einfo "You seem to have logical volumes (LVM) on your system."
2331           eindent
2332           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
2333           eend 0
2334           if checkbootparam 'lvm' ; then
2335              einfo "Bootoption LVM found. Searching for logical volumes:"
2336              /etc/init.d/lvm2 start ; eend $?
2337           fi
2338           eoutdent
2339        fi
2340     fi # check for lvm binary
2341   fi # check for bootoption nolvm
2342   fi # run only in live-cd mode
2343 }
2344 # }}}
2345
2346 # {{{ debnet: setup network based on an existing one found on a partition
2347 config_debnet(){
2348 if checkbootparam 'debnet' ; then
2349  iszsh && setopt shwordsplit
2350  DEVICES="$(< /proc/partitions tail -n +3 | awk '{print "/dev/"$4}' | tr "\n" " ")"
2351  DEVICES="$DEVICES $(ls /dev/mapper/*)"
2352  FOUND_DEBNET=""
2353
2354  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
2355  eindent
2356  if ! mount | grep '/mnt ' 1>/dev/null 2>&1 ; then
2357     for i in $DEVICES; do
2358      if mount -o ro -t auto "$i" /mnt >/dev/null 2>&1; then
2359          einfo "Scanning on $i"
2360        if [ -f /mnt/etc/network/interfaces ]; then
2361          einfo "/etc/network/interfaces found on ${i}" ; eend 0
2362          FOUND_DEBNET="$i"
2363          break
2364        fi
2365        umount /mnt
2366      fi
2367     done
2368
2369    if [ -n "$FOUND_DEBNET" ]; then
2370      einfo "Stopping network."
2371        pump -k 1>/dev/null 2>&1
2372        /etc/init.d/networking stop 1>/dev/null 2>&1 ; eend $?
2373      einfo "Copying Debian network configuration from $FOUND_DEBNET to running system."
2374        rm -rf /etc/network/run
2375        cp -a /mnt/etc/network /etc
2376        rm -rf /etc/network/run
2377        mkdir /etc/network/run
2378        umount /mnt ; eend $?
2379      einfo "Starting network."
2380        invoke-rc.d networking start ; eend $?
2381    else
2382      eerror "/etc/network/interfaces not found." ; eend 1
2383    fi
2384    eoutdent
2385  else
2386   eerror "Error: /mnt already mounted." ; eend 1
2387  fi
2388 fi
2389 }
2390 # }}}
2391
2392 # {{{ check for broken ipw3945 driver which causes problems (especially on hd install)
2393 config_ipw3945() {
2394   if grep -q ipw3945 /proc/modules ; then
2395      if ! iwconfig 2>/dev/null| grep -qe 'IEEE 802' -qe 'unassociated' ; then
2396         ewarn "Broken ipw3945 network interface found, reloading module."
2397         rmmod ipw3945
2398         modprobe ipw3945
2399         eend $?
2400      fi
2401   fi
2402 }
2403 # }}}
2404
2405 # {{{ disable console blanking
2406 config_blanking(){
2407 if checkbootparam 'noblank' ; then
2408   einfo "Bootoption noblank found. Disabling monitor blanking."
2409   setterm -blank 0 ; eend $?
2410 fi
2411 }
2412 # }}}
2413
2414 # {{{ tohd= bootoption
2415 config_tohd()
2416 {
2417   if checkbootparam 'tohd' ; then
2418      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
2419      if [ -z "$TARGET" ] ; then
2420         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
2421         eerror "Please use something like tohd=/dev/sda9." ; eend 1
2422         return 1
2423      fi
2424
2425      if ! [ -b "$TARGET" ] ; then
2426         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
2427         return 1
2428      fi
2429
2430      if grep -q $TARGET /proc/mounts ; then
2431         eerror "$TARGET already mounted, skipping execution of tohd therefore."
2432         eend 1
2433         return 1
2434      fi
2435
2436      local MOUNTDIR=$(mktemp -d)
2437
2438      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
2439         einfo "Copyring live system to $TARGET - this might take a while"
2440         rsync -a --progress /live/image/live $MOUNTDIR
2441         sync
2442         umount "$MOUNTDIR"
2443         eend $?
2444         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
2445      else
2446         eerror "Error when trying to mount $TARGET, sorry."; eend 1
2447         return 1
2448      fi
2449
2450      rmdir "$MOUNTDIR"
2451   fi
2452 }
2453 # }}}
2454
2455 # {{{ grml2hd: automatic installation
2456 config_grml2hd(){
2457
2458 if checkbootparam "BOOT_IMAGE=grml2hd" ; then
2459
2460 if checkbootparam 'user' ; then
2461    NEWUSER=''
2462    NEWUSER="$(getbootparam 'user' 2>>$DEBUG)"
2463    sed -i "s/^NEWUSER=.*/NEWUSER=$NEWUSER/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2464 fi
2465
2466 if checkbootparam 'filesystem' ; then
2467    FILESYSTEM=''
2468    FILESYSTEM="$(getbootparam 'filesystem' 2>>$DEBUG)"
2469    sed -i "s/^FILESYSTEM=.*/FILESYSTEM=$FILESYSTEM/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2470 fi
2471
2472 if checkbootparam 'partition' ; then
2473    PARTITION=''
2474    PARTITION="$(getbootparam 'partition' 2>>$DEBUG)"
2475    # notice: the following checks whether the given partition is available, if not the skip
2476    # execution of grml2hd as it might result in data loss...
2477    if [ -r $PARTITION ] ; then
2478       sed -i "s#^PARTITION=.*#PARTITION=$PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2479    else
2480       ewarn "Partition $PARTITION does not exist. Skipping execution of grml2hd therefore." ; eend 1
2481    fi
2482 fi
2483
2484 if checkbootparam 'mbr' ; then
2485    BOOT_PARTITION=''
2486    BOOT_PARTITION="$(getbootparam 'mbr' 2>>$DEBUG)"
2487    sed -i "s#^BOOT_PARTITION=.*#BOOT_PARTITION=$BOOT_PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2488 fi
2489
2490 cat>|/usr/bin/grml2hd_noninteractive<<EOF
2491 #!/bin/sh
2492 GRML2HD_NONINTERACTIVE='yes' grml2hd
2493 EOF
2494
2495 chmod 755 /usr/bin/grml2hd_noninteractive
2496 einfo "Bootoption grml2hd found. Running automatic installation via grml2hd using /etc/grml2hd/config." && eend 0
2497 if [ -z "$GRML2HD_FAIL" ] ; then
2498    screen /usr/bin/grml2hd_noninteractive ; einfo "Invoking a shell, just exit to continue booting..." ; /bin/zsh
2499 else
2500    ewarn "There was an error adjusting /etc/grml2hd/config. Skipping execution of grml2hd for security reasons." ; eend 1
2501 fi
2502
2503 fi # if checkbootparam "BOOT_IMAGE=grml2hd ...
2504 }
2505 # }}}
2506
2507 # {{{ debootstrap: automatic installation
2508 config_debootstrap(){
2509
2510 if checkbootparam "BOOT_IMAGE=debian2hd" ; then
2511
2512 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
2513
2514 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
2515    eindent
2516    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
2517    eoutdent
2518    exit 1
2519 fi
2520
2521 if checkbootparam 'target' ; then
2522   TARGET=''
2523   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
2524   # notice: the following checks whether the given partition is available, if not the skip
2525   # execution of grml-debootstrap as it might result in data loss...
2526   if ! [ -r "$TARGET" ] ; then
2527      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
2528   fi
2529 else
2530   eindent
2531   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
2532   eoutdent
2533   exit 1
2534 fi
2535
2536 if checkbootparam 'grub' ; then
2537   GRUB=''
2538   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2539 fi
2540
2541 if checkbootparam 'groot' ; then
2542   GROOT=''
2543   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2544 fi
2545
2546 if checkbootparam 'release' ; then
2547   RELEASE=''
2548   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2549 fi
2550
2551 if checkbootparam 'mirror' ; then
2552   MIRROR=''
2553   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2554 fi
2555
2556 if checkbootparam 'boot_append' ; then
2557   BOOT_APPEND=''
2558   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2559 fi
2560
2561 if checkbootparam 'password' ; then
2562   PASSWORD=''
2563   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2564 fi
2565
2566 # now check which options are available
2567 if [ -n "TARGET" ] ; then
2568    TARGETCMD="--target $TARGET"
2569 else
2570    TARGETCMD=''
2571    eindent
2572    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2573    eoutdent
2574    exit 1
2575 fi
2576 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2577 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2578 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2579 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2580 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2581 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2582
2583 # and finally write script and execute it
2584 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2585 #!/bin/sh
2586 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2587 EOF
2588
2589 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2590
2591 screen /usr/bin/grml-debootstrap_noninteractive
2592 einfo "Invoking a shell, just exit to continue booting..."
2593 /bin/zsh
2594
2595 fi # checkbootparam "BOOT_IMAGE=debian2hd
2596 }
2597 # }}}
2598
2599 # {{{ Support customization
2600 config_distri(){
2601 if checkbootparam 'distri'; then
2602   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2603   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2604      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2605      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2606      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2607      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2608   fi
2609 fi
2610 }
2611 # }}}
2612
2613 ### {{{ backwards compatible stuff
2614 config_environment(){
2615   ewarn "config_environment is deprecated. Please set CONFIG_ENVIRONMENT in /etc/grml/autoconfig to 'no'." ; eend 0
2616 }
2617 config_keyboard(){
2618   ewarn "config_keyboard is deprecated. Please set CONFIG_KEYBOARD in /etc/grml/autoconfig to 'no'." ; eend 0
2619 }
2620 # }}}
2621
2622 ## END OF FILE #################################################################
2623 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3