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