Swap position of pre-2009.05 and post-2009.05. [Closes: issue891]
[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    iszsh && setopt localoptions shwordsplit
2035    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
2036    if ! echo $DEBS | grep -q '/'; then
2037      # backwards compatibility: if no path is given get debs from debs/
2038      DEBS="debs/$DEBS"
2039    fi
2040    einfo "Tring to install debian package(s) ${DEBS}"
2041    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
2042    dpkg -i $DEBS ; eend $?
2043 fi
2044 }
2045
2046 config_scripts(){
2047 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
2048    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
2049    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
2050      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
2051    fi
2052    if ! echo $SCRIPTS | grep -q '/'; then
2053      # backwards compatibility: if no path is given get scripts from scripts/
2054      SCRIPTS="scripts/$SCRIPTS"
2055    fi
2056    if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
2057      # we are executing from a GRMLCFG labeled fs
2058      # kick everything we have done before and start over
2059      SCRIPTS="$(cd ${DCSDIR}; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
2060    fi
2061    if [ -n "$SCRIPTS" ]; then
2062      SCRIPTS="${DCSDIR}/$SCRIPTS"
2063      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
2064        einfo "Trying to execute ${SCRIPTS}"
2065        sh -c $SCRIPTS
2066      elif [ -d "$SCRIPTS" ]; then
2067        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
2068        run-parts $SCRIPTS
2069      else
2070        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
2071        sh -c $SCRIPTS
2072      fi
2073    fi
2074 fi
2075 }
2076
2077 config_config(){
2078 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
2079   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
2080   if [ -z "$CONFIG" ]; then
2081     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
2082   fi
2083   if [ -n "$CONFIG" ]; then
2084     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
2085       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
2086
2087       cp -a ${DCSDIR}/${CONFIG}/* /
2088     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
2089       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
2090
2091       cd /
2092       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
2093     else
2094       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
2095     fi
2096   fi
2097 fi
2098 # umount $DCSMP if it was mounted by finddcsdir
2099 # this doesn't really belong here
2100 grep -q '$DCSMP' /proc/mounts && umount $DCSMP
2101 }
2102 # }}}
2103
2104 # {{{ mypath
2105 config_mypath(){
2106 if checkbootparam 'mypath' ; then
2107    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
2108    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
2109    touch /etc/grml/my_path
2110    chmod 644 /etc/grml/my_path
2111    # make sure the directories exist:
2112    eindent
2113    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
2114        if ! [ -d "$i" ] ; then
2115           einfo "Creating directory $i"
2116           mkdir -p "$i" ; eend $?
2117        fi
2118    done
2119    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
2120    eoutdent
2121 fi
2122 }
2123 # }}}
2124
2125 # {{{ distcc
2126 config_distcc(){
2127 if checkbootparam 'distcc' ; then
2128  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
2129  if [ -n "$OPTIONS" ]; then
2130     NET=""
2131     INTERFACE=""
2132     if [ -n "$OPTIONS" ]; then
2133       NET="${OPTIONS%%,*}"
2134       R="${OPTIONS#*,}"
2135       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2136         OPTIONS="$R"
2137         INTERFACE="${OPTIONS%%,*}"
2138         R="${OPTIONS#*,}"
2139       fi
2140     fi
2141  fi
2142  CONFIG=/etc/default/distcc
2143  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
2144  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
2145
2146  if [ -n "$INTERFACE" ] ; then
2147    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2148
2149    counter=10
2150    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
2151      counter=$(( counter-1 ))
2152      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
2153      sleep 3
2154      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2155    done
2156  fi
2157
2158  if [ -n "$IP" ] ; then
2159    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
2160
2161    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
2162    eindent
2163     id distccd >/dev/null 2>&1 || \
2164     (
2165       einfo "Creating distcc user" ; \
2166       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
2167     )
2168
2169     einfo "Starting distcc for network ${NET}, listening on ${IP}."
2170    /etc/init.d/distcc start >/dev/null ; eend $?
2171    eoutdent
2172  else
2173    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
2174  fi
2175 fi
2176
2177 if checkbootparam 'gcc'; then
2178  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
2179  eindent
2180  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
2181  eoutdent
2182  rm -f /usr/bin/gcc
2183  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
2184 fi
2185
2186 if checkbootparam 'gpp'; then
2187  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
2188  eindent
2189   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
2190   if [ -x /usr/bin/g++-${GPP} ] ; then
2191      rm -f /usr/bin/g++
2192      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
2193   fi
2194   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
2195   if [ -x /usr/bin/cpp-${GPP} ] ; then
2196      rm -f /usr/bin/cpp
2197      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
2198   fi
2199  eoutdent
2200 fi
2201
2202 }
2203 # }}}
2204
2205 # {{{ load modules
2206 # Notice: use it only on live-cd system, if running from harddisk please
2207 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
2208 # in /etc/runlevel.conf
2209 config_modules(){
2210 MODULES_FILE=/etc/grml/modules
2211 if checkbootparam 'nomodules' ; then
2212   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
2213 elif [ -z "$INSTALLED" ]; then
2214  if [ -r $MODULES_FILE ] ; then
2215   einfo "Loading modules specified in ${MODULES_FILE}:"
2216   eindent
2217   grep '^[^#]' $MODULES_FILE | \
2218   while read module args; do
2219     [ "$module" ] || continue
2220       einfo "${module}"
2221       modprobe $module $args ; eend $?
2222   done
2223   eoutdent
2224  else
2225   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
2226  fi
2227 fi
2228 }
2229 # }}}
2230
2231 # {{{ 915resolution
2232 config_915resolution(){
2233 if checkbootparam '915resolution' ; then
2234  OPTIONS="$(getbootparam '915resolution' 2>>$DEBUG)"
2235   if [ -x /usr/sbin/915resolution ]; then
2236     CMD=915resolution
2237     MODE=""
2238     XRESO=""
2239     YRESO=""
2240     if [ -n "$OPTIONS" ]; then
2241       # Extra options
2242       MODE="${OPTIONS%%,*}"
2243       R="${OPTIONS#*,}"
2244       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2245         OPTIONS="$R"
2246         XRESO="${OPTIONS%%,*}"
2247         R="${OPTIONS#*,}"
2248         if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2249           OPTIONS="$R"
2250           YRESO="${OPTIONS%%,*}"
2251           R="${OPTIONS#*,}"
2252         fi
2253       fi
2254     fi
2255     einfo "Running 915resolution with options ${MODE} ${XRESO} ${YRESO}."
2256     [ -n "$MODE" ] && [ -n "$XRESO"  ] && [ -n "$YRESO" ]  && ( sh -c "$CMD $MODE $XRESO $YRESO" & )
2257     eend 0
2258   fi
2259 fi
2260 }
2261 # }}}
2262
2263 # {{{ SW-RAID
2264 config_swraid(){
2265   [ -n "$INSTALLED" ] && return 0
2266
2267   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
2268   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
2269      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
2270      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
2271   else
2272     if ! [ -x /sbin/mdadm ] ; then
2273        eerror "mdadm not available, can not execute it." ; eend 1
2274     else
2275
2276        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2277        # find out whether we have a valid configuration file already
2278        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2279           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
2280           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
2281           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
2282         else
2283           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
2284        fi
2285
2286        if ! checkbootparam 'swraid' ; then
2287           eindent
2288           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
2289           eoutdent
2290        else
2291           einfo "Bootoption swraid found. Searching for software RAID arrays:"
2292           eindent
2293            IFSOLD=${IFS:-}
2294            IFS='
2295 '
2296            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
2297                case $line in
2298                  *'No arrays found'*)
2299                    ewarn "$line" ; eend 0
2300                    ;;
2301                  *)
2302                    einfo "$line" ; eend 0
2303                    ;;
2304                esac
2305            done
2306            IFS=$IFSOLD
2307          eoutdent
2308
2309          if [ -r /proc/mdstat ] ; then
2310             eindent
2311             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
2312             if [ -z "$MDSTAT" ] ; then
2313                ewarn "No active arrays found" ; eend 0
2314             else
2315                IFSOLD=${IFS:-}
2316                IFS='
2317 '
2318                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
2319                    einfo "active arrays: $line" ; eend 0
2320                done
2321                IFS=$IFSOLD
2322             fi
2323             eoutdent
2324          fi # /proc/mdstat
2325        fi # bootoption swraid
2326
2327      fi # is /sbin/mdadm executable?
2328   fi # check for bootoptions
2329 }
2330 # }}}
2331
2332 # {{{ dmraid
2333 config_dmraid(){
2334   [ -n "$INSTALLED" ] && return 0
2335
2336   if checkbootparam 'nodmraid' ; then
2337     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
2338     return 0
2339   fi
2340
2341   if ! [ -x /sbin/dmraid ] ; then
2342     eerror "dmraid not available, can not execute it." ; eend 1
2343     return
2344   fi
2345
2346   dmraid_wrapper() {
2347     # usage: dmraid_wrapper <dmraid_option>
2348     [ -n "$1" ] || return 1
2349
2350     IFSOLD=${IFS:-}
2351     IFS='
2352 '
2353     eindent
2354
2355     for line in $(dmraid $1 ; echo errcode:$?); do
2356       case $line in
2357         *'no block devices found'*)
2358           einfo "No block devices found" ; eend 0
2359           break
2360           ;;
2361         *'no raid disks'*)
2362           einfo "No active dmraid devices found" ; eend 0
2363           break
2364           ;;
2365         errcode:0)
2366           eend 0;
2367           ;;
2368         errcode:1)
2369           eend 1
2370           ;;
2371         *)
2372           einfo "$line"
2373           ;;
2374       esac
2375     done
2376
2377     eoutdent
2378     IFS=$IFSOLD
2379   }
2380
2381   if checkbootparam 'dmraid' ; then
2382     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
2383     if [ "$ACTION" = "off" ] ; then
2384       # Deactivates all active software RAID sets:
2385       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
2386       dmraid_wrapper -an
2387     else
2388       # Activate all software RAID sets discovered:
2389       einfo "Activating present dmraid sets (as requested via dmraid):"
2390       dmraid_wrapper -ay
2391     fi
2392
2393     return
2394   fi
2395
2396   # by default (no special bootoptions) discover all software RAID devices:
2397   einfo "Searching for any present dmraid sets:"
2398   dmraid_wrapper -r
2399 }
2400 # }}}
2401
2402 # {{{ LVM (Logical Volumes)
2403 config_lvm(){
2404   [ -n "$INSTALLED" ] && return 0
2405
2406   if checkbootparam 'nolvm' ; then
2407      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
2408   else
2409     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
2410     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
2411        eerror "LVM not available, can not execute it." ; eend 1
2412     else
2413        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
2414           einfo "You seem to have logical volumes (LVM) on your system."
2415           eindent
2416           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
2417           eend 0
2418           if checkbootparam 'lvm' ; then
2419              einfo "Bootoption LVM found. Searching for logical volumes:"
2420              /etc/init.d/lvm2 start ; eend $?
2421           fi
2422           eoutdent
2423        fi
2424     fi # check for lvm binary
2425   fi # check for bootoption nolvm
2426 }
2427 # }}}
2428
2429 # {{{ debnet: setup network based on an existing one found on a partition
2430 config_debnet(){
2431 if checkbootparam 'debnet' ; then
2432  iszsh && setopt localoptions shwordsplit
2433  DEVICES="$(< /proc/partitions tail -n +3 | awk '{print "/dev/"$4}' | tr "\n" " ")"
2434  DEVICES="$DEVICES $(ls /dev/mapper/*)"
2435  FOUND_DEBNET=""
2436
2437  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
2438  eindent
2439  if ! mount | grep '/mnt ' >/dev/null 2>&1 ; then
2440     for i in $DEVICES; do
2441      if mount -o ro -t auto "$i" /mnt >/dev/null 2>&1; then
2442          einfo "Scanning on $i"
2443        if [ -f /mnt/etc/network/interfaces ]; then
2444          einfo "/etc/network/interfaces found on ${i}" ; eend 0
2445          FOUND_DEBNET="$i"
2446          break
2447        fi
2448        umount /mnt
2449      fi
2450     done
2451
2452    if [ -n "$FOUND_DEBNET" ]; then
2453      einfo "Stopping network."
2454        pump -k >/dev/null 2>&1
2455        /etc/init.d/networking stop >/dev/null 2>&1 ; eend $?
2456      einfo "Copying Debian network configuration from $FOUND_DEBNET to running system."
2457        rm -rf /etc/network/run
2458        cp -a /mnt/etc/network /etc
2459        rm -rf /etc/network/run
2460        mkdir /etc/network/run
2461        umount /mnt ; eend $?
2462      einfo "Starting network."
2463        invoke-rc.d networking start ; eend $?
2464    else
2465      eerror "/etc/network/interfaces not found." ; eend 1
2466    fi
2467    eoutdent
2468  else
2469   eerror "Error: /mnt already mounted." ; eend 1
2470  fi
2471 fi
2472 }
2473 # }}}
2474
2475 # {{{ check for broken ipw3945 driver which causes problems (especially on hd install)
2476 config_ipw3945() {
2477   if grep -q ipw3945 /proc/modules ; then
2478      if ! iwconfig 2>/dev/null| grep -qe 'IEEE 802' -qe 'unassociated' ; then
2479         ewarn "Broken ipw3945 network interface found, reloading module."
2480         rmmod ipw3945
2481         modprobe ipw3945
2482         eend $?
2483      fi
2484   fi
2485 }
2486 # }}}
2487
2488 # {{{ disable console blanking
2489 config_blanking(){
2490 if checkbootparam 'noblank' ; then
2491   einfo "Bootoption noblank found. Disabling monitor blanking."
2492   setterm -blank 0 ; eend $?
2493 fi
2494 }
2495 # }}}
2496
2497 # {{{ tohd= bootoption
2498 config_tohd()
2499 {
2500   if checkbootparam 'tohd' ; then
2501      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
2502      if [ -z "$TARGET" ] ; then
2503         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
2504         eerror "Please use something like tohd=/dev/sda9." ; eend 1
2505         return 1
2506      fi
2507
2508      if ! [ -b "$TARGET" ] ; then
2509         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
2510         return 1
2511      fi
2512
2513      if grep -q $TARGET /proc/mounts ; then
2514         eerror "$TARGET already mounted, skipping execution of tohd therefore."
2515         eend 1
2516         return 1
2517      fi
2518
2519      local MOUNTDIR=$(mktemp -d)
2520
2521      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
2522         einfo "Copyring live system to $TARGET - this might take a while"
2523         rsync -a --progress /live/image/live $MOUNTDIR
2524         sync
2525         umount "$MOUNTDIR"
2526         eend $?
2527         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
2528      else
2529         eerror "Error when trying to mount $TARGET, sorry."; eend 1
2530         return 1
2531      fi
2532
2533      rmdir "$MOUNTDIR"
2534   fi
2535 }
2536 # }}}
2537
2538 # {{{ grml2hd: automatic installation
2539 config_grml2hd(){
2540
2541 if checkbootparam "BOOT_IMAGE=grml2hd" ; then
2542
2543 if checkbootparam 'user' ; then
2544    NEWUSER=''
2545    NEWUSER="$(getbootparam 'user' 2>>$DEBUG)"
2546    sed -i "s/^NEWUSER=.*/NEWUSER=$NEWUSER/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2547 fi
2548
2549 if checkbootparam 'filesystem' ; then
2550    FILESYSTEM=''
2551    FILESYSTEM="$(getbootparam 'filesystem' 2>>$DEBUG)"
2552    sed -i "s/^FILESYSTEM=.*/FILESYSTEM=$FILESYSTEM/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2553 fi
2554
2555 if checkbootparam 'partition' ; then
2556    PARTITION=''
2557    PARTITION="$(getbootparam 'partition' 2>>$DEBUG)"
2558    # notice: the following checks whether the given partition is available, if not the skip
2559    # execution of grml2hd as it might result in data loss...
2560    if [ -r $PARTITION ] ; then
2561       sed -i "s#^PARTITION=.*#PARTITION=$PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2562    else
2563       ewarn "Partition $PARTITION does not exist. Skipping execution of grml2hd therefore." ; eend 1
2564    fi
2565 fi
2566
2567 if checkbootparam 'mbr' ; then
2568    BOOT_PARTITION=''
2569    BOOT_PARTITION="$(getbootparam 'mbr' 2>>$DEBUG)"
2570    sed -i "s#^BOOT_PARTITION=.*#BOOT_PARTITION=$BOOT_PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2571 fi
2572
2573 cat>|/usr/bin/grml2hd_noninteractive<<EOF
2574 #!/bin/sh
2575 GRML2HD_NONINTERACTIVE='yes' grml2hd
2576 EOF
2577
2578 chmod 755 /usr/bin/grml2hd_noninteractive
2579 einfo "Bootoption grml2hd found. Running automatic installation via grml2hd using /etc/grml2hd/config." && eend 0
2580 if [ -z "$GRML2HD_FAIL" ] ; then
2581    screen /usr/bin/grml2hd_noninteractive ; einfo "Invoking a shell, just exit to continue booting..." ; /bin/zsh
2582 else
2583    ewarn "There was an error adjusting /etc/grml2hd/config. Skipping execution of grml2hd for security reasons." ; eend 1
2584 fi
2585
2586 fi # if checkbootparam "BOOT_IMAGE=grml2hd ...
2587 }
2588 # }}}
2589
2590 # {{{ debootstrap: automatic installation
2591 config_debootstrap(){
2592
2593 if checkbootparam "BOOT_IMAGE=debian2hd" ; then
2594
2595 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
2596
2597 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
2598    eindent
2599    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
2600    eoutdent
2601    exit 1
2602 fi
2603
2604 if checkbootparam 'target' ; then
2605   TARGET=''
2606   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
2607   # notice: the following checks whether the given partition is available, if not the skip
2608   # execution of grml-debootstrap as it might result in data loss...
2609   if ! [ -r "$TARGET" ] ; then
2610      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
2611   fi
2612 else
2613   eindent
2614   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
2615   eoutdent
2616   exit 1
2617 fi
2618
2619 if checkbootparam 'grub' ; then
2620   GRUB=''
2621   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2622 fi
2623
2624 if checkbootparam 'groot' ; then
2625   GROOT=''
2626   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2627 fi
2628
2629 if checkbootparam 'release' ; then
2630   RELEASE=''
2631   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2632 fi
2633
2634 if checkbootparam 'mirror' ; then
2635   MIRROR=''
2636   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2637 fi
2638
2639 if checkbootparam 'boot_append' ; then
2640   BOOT_APPEND=''
2641   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2642 fi
2643
2644 if checkbootparam 'password' ; then
2645   PASSWORD=''
2646   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2647 fi
2648
2649 # now check which options are available
2650 if [ -n "TARGET" ] ; then
2651    TARGETCMD="--target $TARGET"
2652 else
2653    TARGETCMD=''
2654    eindent
2655    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2656    eoutdent
2657    exit 1
2658 fi
2659 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2660 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2661 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2662 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2663 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2664 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2665
2666 # and finally write script and execute it
2667 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2668 #!/bin/sh
2669 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2670 EOF
2671
2672 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2673
2674 screen /usr/bin/grml-debootstrap_noninteractive
2675 einfo "Invoking a shell, just exit to continue booting..."
2676 /bin/zsh
2677
2678 fi # checkbootparam "BOOT_IMAGE=debian2hd
2679 }
2680 # }}}
2681
2682 # {{{ Support customization
2683 config_distri(){
2684 if checkbootparam 'distri'; then
2685   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2686   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2687      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2688      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2689      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2690      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2691   fi
2692 fi
2693 }
2694 # }}}
2695
2696 ### {{{ backwards compatible stuff
2697 config_environment(){
2698   ewarn "config_environment is deprecated. Please set CONFIG_ENVIRONMENT in /etc/grml/autoconfig to 'no'." ; eend 0
2699 }
2700 config_keyboard(){
2701   ewarn "config_keyboard is deprecated. Please set CONFIG_KEYBOARD in /etc/grml/autoconfig to 'no'." ; eend 0
2702 }
2703 # }}}
2704
2705 ## END OF FILE #################################################################
2706 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3