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