6fa4d37c1398d72e4d08e05bee8dd4002b084505
[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 ### }}}
102
103 # {{{ filesystems (proc, pts, sys) and fixes
104 mount_proc(){
105   [ -f /proc/version ] || mount -t proc /proc /proc 2>/dev/null
106 }
107
108 mount_pts(){
109   grep -q "/dev/pts" /proc/mounts || mount -t devpts /dev/pts /dev/pts 2>/dev/null
110 }
111
112 mount_sys(){
113   [ -d /sys/devices ] || mount -t sysfs /sys /sys 2>/dev/null
114 }
115 # }}}
116
117 # {{{ Check if we are running in live mode or from HD
118 INSTALLED=""
119 [ -e /etc/grml_cd ] || INSTALLED="yes"
120
121 # testcd
122 TESTCD=""
123 checkbootparam 'testcd' >>$DEBUG 2>&1 && TESTCD="yes"
124 # }}}
125
126 # {{{ source lsb-functions , color handling
127 if checkbootparam 'nocolor'; then
128   RC_NOCOLOR=yes
129   . /etc/grml/lsb-functions
130   einfo "Disabling colors in bootsequence as requested on commandline." ; eend 0
131 else
132   . /etc/grml/lsb-functions
133   . /etc/grml_colors
134 fi
135 # }}}
136
137 # {{{ debug
138 config_debug(){
139  checkbootparam 'debug'            && BOOTDEBUG="yes"
140  checkbootparam "BOOT_IMAGE=debug" && BOOTDEBUG="yes"
141
142  rundebugshell(){
143   if [ -n "$BOOTDEBUG" ]; then
144      einfo "Starting intermediate shell stage $stage as requested by \"debug\" option."
145      if [ grep -q "debug=noscreen" "$CMDLINE" ] ; then
146         einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
147         einfo "Just exit the shell to continue boot process..."
148         /bin/zsh
149      else
150         eindent
151         if [ -r /etc/grml/screenrc ] ; then
152            einfo "Starting GNU screen to be able to use a full featured shell environment."
153            einfo "Just exit the shells (and therefore screen) to continue boot process..."
154            /bin/zsh -c "screen -c /etc/grml/screenrc"
155         else
156            einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
157            einfo "Just exit the shell to continue boot process..."
158            /bin/zsh
159         fi
160         eoutdent
161      fi
162   fi
163  }
164 }
165 # }}}
166
167 # {{{ log
168 config_log(){
169 if checkbootparam 'log' || checkbootparam 'debug' ; then
170    export DEBUG="/tmp/grml.log.`date +%Y%m%d`"
171    touch $DEBUG
172    einfo "Bootparameter log found. Log files: ${DEBUG} and /var/log/boot"
173    eindent
174      einfo "Starting bootlogd." # known to be *very* unreliable :(
175      bootlogd -r -c >>$DEBUG 2>&1 ; eend $?
176    eoutdent
177 else
178    DEBUG="/dev/null"
179 fi
180 }
181 # }}}
182
183 # {{{ set firmware timeout via bootparam
184 config_fwtimeout(){
185  if checkbootparam 'fwtimeout' ; then
186    TIMEOUT="$(getbootparam 'fwtimeout' 2>>$DEBUG)"
187    einfo "Bootoption fwtimeout found. (Re)Loading firmware_class module."
188    rmmod firmware_class >>$DEBUG 2>&1
189    modprobe firmware_class ; eend $?
190  fi
191  if [ -z "$TIMEOUT" ] ; then
192    TIMEOUT="100" # linux kernel default: 10
193  fi
194  if [ -f /sys/class/firmware/timeout ] ; then
195    einfo "Setting timeout for firmware loading to ${TIMEOUT}."
196    echo 100 > /sys/class/firmware/timeout ; eend $?
197  fi
198 }
199 # }}}
200
201 ### {{{ language configuration / localization
202 config_language(){
203
204  einfo "Activating language settings:"
205  eindent
206
207  # people can specify $LANGUAGE and $CONSOLEFONT in a config file
208  [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
209
210  # check for bootoption which overrides config from /etc/grml/autoconfig
211  BOOT_LANGUAGE="$(getbootparam 'lang' 2>>$DEBUG)"
212  [ -n "$BOOT_LANGUAGE" ] && LANGUAGE="$BOOT_LANGUAGE"
213
214  # set default to 'en' in live-cd mode iff $LANGUAGE is not set yet
215  if [ -z "$INSTALLED" ] ; then
216     [ -n "$LANGUAGE" ] || LANGUAGE='en'
217  fi
218
219  if [ -x /usr/sbin/grml-setlang ] ; then
220    # if bootoption lang is used update /etc/default/locale accordingly
221    if [ -n "$BOOT_LANGUAGE" ] ; then
222      checkgrmlsmall && /usr/sbin/grml-setlang "POSIX" || /usr/sbin/grml-setlang "$LANGUAGE"
223    # otherwise default to lang=en
224    else
225      checkgrmlsmall && /usr/sbin/grml-setlang "POSIX" || /usr/sbin/grml-setlang "en"
226    fi
227  fi
228
229  # set console font
230  if [ -z "$CONSOLEFONT" ] ; then
231     if ! checkbootparam 'nodefaultfont' >>$DEBUG 2>&1 ; then
232        if [ -r /usr/share/consolefonts/Uni3-Terminus16.psf.gz ] ; then
233           CONSOLEFONT='Uni3-Terminus16'
234        else
235           ewarn "/usr/share/consolefonts/Uni3-Terminus16.psf.gz not available. Please upgrade package console-terminus." ; eend 1
236        fi
237        if ! hasfb ; then
238           CONSOLEFONT='Lat15-Terminus16'
239        fi
240     fi
241  fi
242
243  # export it now, so error messages get translated, too
244  if checkgrmlsmall ; then
245     export LANG='C' # grml-small does not provide any further locales
246  else
247     [ -r /etc/default/locale ] && . /etc/default/locale
248     export LANG LANGUAGE
249  fi
250
251  # configure keyboard layout, read in already set values first:
252  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
253
254  # now allow keyboard override by boot commandline for later use:
255  KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
256  [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
257  # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
258  [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
259  [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
260
261  # modify /etc/sysconfig/keyboard only in live-cd mode:
262  if [ -z "$INSTALLED" ] ; then
263
264    local LANGUAGE="$BOOT_LANGUAGE"
265    . /etc/grml/language-functions
266    # allow setting xkeyboard explicitly different than console keyboard
267    KXKEYBOARD="$(getbootparam 'xkeyboard' 2>>$DEBUG)"
268    if [ -n "$KXKEYBOARD" ]; then
269       XKEYBOARD="$KXKEYBOARD"
270       KDEKEYBOARD="$KXKEYBOARD"
271    elif [ -n "$KKEYBOARD" ]; then
272       XKEYBOARD="$KKEYBOARD"
273       KDEKEYBOARD="$KKEYBOARD"
274    fi
275
276    # duplicate of previous code to make sure /etc/grml/language-functions
277    # does not overwrite our values....
278    # now allow keyboard override by boot commandline for later use:
279    KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
280    [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
281    # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
282    [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
283    [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
284
285    # write keyboard related variables to file for later use
286    [ -d /etc/sysconfig ] || mkdir /etc/sysconfig
287    if ! [ -e /etc/sysconfig/keyboard ] ; then
288       echo "KEYTABLE=\"$KEYTABLE\""          > /etc/sysconfig/keyboard
289       echo "XKEYBOARD=\"$XKEYBOARD\""       >> /etc/sysconfig/keyboard
290       echo "KDEKEYBOARD=\"$KDEKEYBOARD\""   >> /etc/sysconfig/keyboard
291       echo "KDEKEYBOARDS=\"$KDEKEYBOARDS\"" >> /etc/sysconfig/keyboard
292    fi
293  fi
294
295  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
296
297  # activate unicode console if running within utf8 environment
298  if [ -r /etc/default/locale ] ; then
299     if grep -q "LANG=.*UTF" /etc/default/locale ; then
300        einfo "Setting up unicode environment."
301        unicode_start >>$DEBUG 2>&1 ; eend $?
302     fi
303  fi
304
305  # Set default keyboard before interactive setup
306  if [ -n "$KEYTABLE" ] ; then
307     einfo "Running loadkeys for ${WHITE}${KEYTABLE}${NORMAL} in background"
308     loadkeys -q $KEYTABLE &
309     eend $?
310  fi
311
312  # we have to set up all consoles, therefore loop it over all ttys:
313  NUM_CONSOLES=$(fgconsole --next-available 2>/dev/null)
314  if [ -n "$NUM_CONSOLES" ] ; then
315     NUM_CONSOLES=$(expr ${NUM_CONSOLES} - 1)
316     [ ${NUM_CONSOLES} -eq 1 ] && NUM_CONSOLES=6
317  fi
318  CUR_CONSOLE=$(fgconsole 2>/dev/null)
319
320  if [ -x "$(which setfont)" ] ; then
321     use_setfont=true
322  elif [ -x "$(which consolechars)" ] ; then
323     use_consolechars=true
324  else
325     eerror "Neither setfont nor consolechars tool present, can not set font."
326     eend 1
327     return 1
328  fi
329
330  if [ -n "$CHARMAP" ] ; then
331     einfo "Setting font to ${CHARMAP}"
332     RC=0
333     for vc in $(seq 0 ${NUM_CONSOLES}) ; do
334         if $use_setfont ; then
335           setfont -C /dev/tty${vc} $CHARMAP ; RC=$?
336         elif $use_consolechars ; then
337           consolechars --tty=/dev/tty${vc} -m ${CHARMAP} ; RC=$?
338         fi
339     done
340     if [ -n "$CUR_CONSOLE" ] ; then
341        [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
342     fi
343     eend $RC
344  fi
345
346  if checkbootparam 'noconsolefont' ; then
347     ewarn "Skipping setting console font as requested on boot commandline." ; eend 0
348  else
349     if [ -n "$CONSOLEFONT" ] ; then
350        einfo "Setting font to ${CONSOLEFONT}"
351        RC=0
352        for vc in $(seq 0 ${NUM_CONSOLES}) ; do
353            if $use_setfont ; then
354              setfont -C /dev/tty${vc} ${CONSOLEFONT} ; RC=$?
355            elif $use_consolechars ; then
356              consolechars --tty=/dev/tty${vc} -f ${CONSOLEFONT} ; RC=$?
357            fi
358        done
359        if [ -n "$CUR_CONSOLE" ] ; then
360           [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
361        fi
362        eend $RC
363     fi
364  fi
365
366  eoutdent
367 }
368 # }}}
369
370 # {{{ Set hostname
371 config_hostname(){
372  if checkbootparam 'hostname' ; then
373   HOSTNAME="$(getbootparam 'hostname' 2>>$DEBUG)"
374   if [ -z "$HOSTNAME" ] && [ -x /usr/bin/random-hostname ] ; then
375      einfo "Generating random hostname as no hostname was specified."
376      HOSTNAME="$(/usr/bin/random-hostname)"
377      eend $?
378   fi
379   einfo "Setting hostname to $HOSTNAME as requested."
380   grml-hostname $HOSTNAME >>$DEBUG ; RC=$?
381   [ "$RC" = "0" ] && hostname $HOSTNAME
382   eend $RC
383  else
384   hostname --file /etc/hostname
385  fi
386 }
387 # }}}
388
389 # fstabuser (needed when running from harddisk with username != grml {{{
390 config_userfstab(){
391   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
392   if [ -n "$CONFIG_FSTAB_USER" ] ; then
393      fstabuser="$CONFIG_FSTAB_USER"
394   else
395      fstabuser=$(getent passwd 1000 | cut -d: -f1)
396   fi
397   # if not yet set fall back to default 'grml' user
398   [ -n "$fstabuser" ] || fstabuser='grml'
399 }
400 # }}}
401
402 # {{{ Set clock (Local time is more often used than GMT, so it is default)
403 config_time(){
404  # don't touch the files if running from harddisk:
405  if [ -z "$INSTALLED" ]; then
406     # The default hardware clock timezone is stated as representing local time.
407     UTC="--localtime"
408     grep -q "^UTC=" /etc/default/rcS || echo "UTC=no" >> /etc/default/rcS
409     checkbootparam 'utc'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
410     checkbootparam 'gmt'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
411     checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=no|"  /etc/default/rcS
412     grep -q -i "^UTC=yes" /etc/default/rcS && UTC="-u"
413     # hwclock uses the TZ variable
414     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
415     [ -z "$KTZ" ] && [ -r /etc/timezone ] && KTZ=$(cat /etc/timezone)
416     if [ ! -f "/usr/share/zoneinfo/$KTZ" ] ; then
417        ewarn "Warning: unknown timezone $KTZ" ; eend 1
418        KTZ="Europe/Vienna"
419        ewarn "Falling back to timezone $KTZ" ; eend 0
420     fi
421
422     if ! [ -r /dev/rtc ] ; then
423       ewarn "Warning: realtime clock not available, trying to execute hwclock anyway." ; eend 0
424     fi
425
426     ERROR=$(TZ="$KTZ" hwclock $UTC -s 2>&1 | head -1) ; RC=$?
427     if [ -n "$ERROR" ] ; then
428        eindent
429        ERROR=$(TZ="$KTZ" hwclock $UTC -s --directisa 2>&1 | head -1)
430        if [ -n "$ERROR" ] ; then
431           eerror "Problem running hwclock: $ERROR" ; eend 1
432        fi
433        eoutdent
434     fi
435
436  fi
437 }
438 # }}}
439
440 # {{{ print kernel info
441 config_kernel(){
442   vmware-detect &>/dev/null && VMWARE="inside ${WHITE}VMware/Qemu${NORMAL}"
443   [ -d /proc/xen ] && VMWARE='' # vmware-detect returns '0' when running with a Xen-enabled kernel
444   einfo "Running Linux Kernel $KERNEL $VMWARE" ; eend 0
445   if [ -r /proc/cpuinfo ] ; then
446      if egrep -q '^flags.*(vmx|svm)' /proc/cpuinfo ; then
447        eindent
448        einfo 'CPU(s) featuring virtualization technology detected' ; eend 0
449        eoutdent
450      fi
451   fi
452   if [ -d /proc/xen ] ; then
453      eindent
454      einfo 'Running kernel featuring support for Xen detected' ; eend 0
455      eoutdent
456   fi
457 }
458 # }}}
459
460 # {{{ ld.so.cache + depmod
461 config_ld_mod(){
462 if [ -n "$INSTALLED" ]; then
463  if ! [ -r /etc/grml.first.boot ] ; then
464   einfo "Running from HD for the first time, regenerate ld.so.cache and modules.dep:"
465   eindent
466 # Regenerate ld.so.cache and module dependencies on HD
467     einfo "Running ldconfig" ; ldconfig  ; eend $?
468     einfo "Running depmod"   ; depmod -a ; eend $?
469     touch /etc/grml.first.boot
470     eend 0
471   eoutdent
472  fi
473 fi
474 }
475 # }}}
476
477 # {{{ timezone
478 config_timezone(){
479  # don't touch the files if running from harddisk:
480  if [ -z "$INSTALLED" ]; then
481     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
482     if [ -n "$KTZ" ] ; then
483        if [ ! -f "/usr/share/zoneinfo/$KTZ" ]
484        then
485           ewarn "Warning: unknown timezone $KTZ"; eend 0
486        else
487           einfo "Setting timezone."
488           # update debconf
489           area=$(echo $KTZ | cut -d '/' -f1)
490           zone=$(echo $KTZ | cut -d '/' -f2)
491           echo "tzdata tzdata/Areas       select $area" | debconf-set-selections
492           echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections
493           # update files
494           echo $KTZ > /etc/timezone
495           rm -f /etc/localtime
496           cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $?
497        fi
498     fi
499  fi
500 }
501 # }}}
502
503 # small computer / nearly no ram {{{
504 config_small(){
505
506 RAM=$(/usr/bin/gawk '/MemTotal/{print $2}' /proc/meminfo)
507 # MEM=$(/usr/bin/gawk 'BEGIN{m=0};/MemFree|Cached|SwapFree/{m+=$2};END{print m}' /proc/meminfo)
508 eindent
509
510 if checkbootparam 'small'; then
511   einfo "Information: ${RAM} kB of RAM available." ; eend 0
512   einfo "Bootoption small detected. Activating small system."
513   if [ -r /etc/inittab.small ] ; then
514     mv /etc/inittab /etc/inittab.normal
515     mv /etc/inittab.small /etc/inittab
516   else
517     sed -i 's/^9/#&/' /etc/inittab
518     sed -i 's/^10/#&/' /etc/inittab
519     sed -i 's/^11/#&/' /etc/inittab
520     sed -i 's/^12/#&/' /etc/inittab
521   fi
522   /sbin/telinit q ; eend $?
523 else
524   if checkgrmlsmall ; then
525     if [[ $RAM -lt 25000 ]] ; then
526       ewarn "Information: ${RAM} kB of RAM available." ; eend 1
527       ewarn "At least 32MB of RAM should be available for grml-small." ; eend 1
528       ewarn "Use the bootoption small to save some more MB of memory usage." ; eend 0
529       ewarn "Dropping you into a rescue shell. To continue booting exit the shell." ; eend 0
530       /bin/zsh --login
531     else
532       einfo "Information: ${RAM} kB of RAM available." ; eend 0
533     fi
534   else
535     if [[ $RAM -lt 58000 ]] ; then
536       ewarn "Information: ${RAM} kB of RAM available." ; eend 1
537       ewarn "At least 64MB of RAM should be available for grml." ; eend 1
538       ewarn "Use the bootoption small to save some more MB of memory usage." ; eend 0
539       ewarn "Dropping you into a rescue shell. To continue booting exit the shell." ; eend 0
540       /bin/zsh --login
541     else
542       einfo "Information: ${RAM} kB of RAM available." ; eend 0
543     fi
544   fi
545 fi
546 eoutdent
547 }
548 # }}}
549
550 # skip startup of w3m {{{
551 config_fast(){
552 if checkbootparam 'fast'; then
553   ewarn "Bootoption fast detected. Skipping startup of grml-quickconfig."
554     sed -i 's#^1:.*#1:12345:respawn:/usr/bin/openvt -f -c 1 -w -- /bin/zsh#' /etc/inittab
555   /sbin/telinit q ; eend $?
556 fi
557 }
558 # }}}
559
560 # activate serial console {{{
561 config_console(){
562 if checkbootparam 'console'; then
563   local line
564   local ws
565   ws='   '
566
567   einfo "Bootoption for serial console detected:"
568
569   line="$CMDLINE x "
570   this=""
571   line="${line#*[$ws]}"
572   local telinitq=""
573   while [ -n "$line" ]; do
574     case "$this" in
575       console=*)
576         local serial="$this"
577         local device="${this%%,*}"
578         local device="${device##*=}"
579         if echo $serial | grep -q ttyS ; then
580           local option="${serial##*,}"
581           # default (works for kvm & CO):
582           local speed="115200,57600,38400,19200,9600,4800,2400,1200";
583           # ... unless overriden by command line:
584           case "$option" in
585             115200*) speed=115200 ;;
586              57600*) speed=57600 ;;
587              38400*) speed=38400 ;;
588              19200*) speed=19200 ;;
589               9600*) speed=9600 ;;
590               4800*) speed=4800 ;;
591               2400*) speed=2400 ;;
592               1200*) speed=1200 ;;
593           esac
594           eindent
595             einfo "Activating console login on device ${device} with speed ${speed}."
596             local number="${device#ttyS}"
597             sed -i "/^T$number:/d;/^#grmlserial#/iT$number:23:respawn:/bin/bash -c \"/sbin/getty -L $device -l /usr/share/grml-scripts/run-welcome $speed vt100 || sleep 30\"" /etc/inittab
598             eend $?
599             telinitq="1"
600           eoutdent
601         fi
602         ;;
603     esac
604     this="${line%%[$ws]*}"
605     line="${line#*[$ws]}"
606   done
607
608   if [ -n "$telinitq" ]; then
609     /sbin/telinit q
610   fi
611   eend $?
612 fi
613 }
614 # }}}
615
616 # {{{ Bring up loopback interface now
617 config_local_net(){
618  if [ -z "$INSTALLED" ] ; then
619     if grep -q 'iface lo inet loopback' /etc/network/interfaces 2>/dev/null ; then
620        grep -q lo=lo /etc/network/run/ifstate 2>/dev/null || ifup lo
621     else
622        ifconfig lo up
623     fi
624  fi
625 }
626 # }}}
627
628 # {{{ copy passwd-lockfile to ramdisk (fix unionfs-behaviour)
629 # otherwise we will get: passwd: Authentication token lock busy
630 config_fix_passwd(){
631  if [ -z "$INSTALLED" ] ; then
632   touch /etc/.pwd.lock
633  fi
634 }
635 # }}}
636
637 # {{{ CD Checker
638 config_testcd(){
639 if [ -n "$TESTCD" ]; then
640    einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
641    einfo "Reading files and checking against GRML/md5sums, this may take a while..."
642    echo -n "${RED}"
643
644    if [ -n "${LIVECD_PATH}"/GRML ] ; then
645       ( cd "${LIVECD_PATH}"/GRML ; rm -f /tmp/md5sum.log ; md5sum -c md5sums 2>&1 | tee /tmp/md5sum.log ; RC=$? )
646    else
647       echo "${RED} *** Error: Could not find md5sum file.                           ***"
648    fi
649
650    if [ "$RC" = "0" ]; then
651       einfo "Everything looks OK" ; eend 0
652    else
653       eerror 'Checksum failed for theses files:' ; eend 1
654       egrep -v '(^md5sum:|OK$)' /tmp/md5sum.log
655       eerror 'Data on the grml medium is possibly incomplete/damaged or...'
656       eerror '... RAM of your computer is broken.' ; eend 1
657       einfon "Hit return to continue, or press the reset button to quit."
658      read a
659    fi
660
661    eend 0
662 fi
663 }
664 # }}}
665
666 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
667 config_blacklist(){
668 if checkbootparam 'blacklist' ; then
669  if [ -z "$INSTALLED" ]; then
670   einfo "Bootoption blacklist found."
671   BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
672   BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
673   if [ -n "$BLACK" ] ; then
674     for module in $(echo ${BLACK//,/ }) ; do
675         einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
676         echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
677         echo "blacklist $module"     >> "$BLACKLIST_FILE"
678         echo "alias     $module off" >> "$BLACKLIST_FILE"
679         echo "# end   entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
680     done
681   else
682    eerror "No given module for blacklist found. Blacklisting will not work therefore."
683   fi
684  else
685   ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
686   eindent
687    einfo "Please blacklist the module(s) manually using the 'blacklist' script."
688   eoutdent
689  fi
690 fi
691 }
692 # }}}
693
694 # {{{ ACPI
695 config_acpi(){
696 if checkbootparam 'noacpi'; then
697   ewarn "ACPI: Not loading modules as requested by boot option \"noacpi\"." ; eend 0
698 elif checkbootparam 'nogrmlacpi' ; then
699   ewarn "ACPI: Not loading modules as requested by boot option \"nogrmlacpi\"." ; eend 0
700 else
701   einfo "ACPI: Loading modules (disable with boot option noacpi / nogrmlacpi): "
702   eindent
703   found=""
704   for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
705     basename="${a##*/}"
706     basename="${basename%%.*}"
707     case "$basename" in *_acpi)
708      egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
709     esac
710     modprobe $basename >>$DEBUG 2>&1 && found="yes"
711     local BASE="$BASE $basename"
712   done
713   if [ -n "$found" ] ; then
714     einfo "$BASE"  ; eend 0
715   else
716     ewarn "(none)" ; eend 1
717   fi
718   if ! ps x 2>>$DEBUG | grep -q /usr/sbin/acpid ; then
719     einfo "Starting acpi daemon."
720     /etc/init.d/acpid start >>$DEBUG 2>&1 ; eend $?
721   else
722     ewarn "acpi daemon already running."
723     eend 0
724   fi
725   eoutdent
726 fi
727 }
728 # }}}
729
730 # {{{ Collect partitions from /proc/partitions first for enabling DMA
731 check_partitions(){
732 partitions=""
733 IDEDISKS=""
734 while read major minor blocks partition relax; do
735   partition="${partition##*/}"
736   [ -z "$partition" -o ! -e "/dev/$partition" ] && continue
737   case "$partition" in
738     hd?) IDEDISKS="$IDEDISKS $partition";;                # IDE  Harddisk, entire disk
739     sd?) ;;                                               # SCSI Harddisk, entire disk
740 #    [hs]d*) partitions="$partitions /dev/$partition";;    # IDE or SCSI disk partition
741     [hs]d*|ub*) partitions="$partitions /dev/$partition";;    # IDE, USB or SCSI disk partition
742   esac
743 done <<EOT
744 $(awk 'BEGIN{old="__start"}{if($0==old){exit}else{old=$0;if($4&&$4!="name"){print $0}}}' /proc/partitions)
745 EOT
746 }
747 check_partitions >/dev/null 2>&1 # avoid output "check_partitions:3: read-only file system"
748 # }}}
749
750 # {{{ Enable DMA for all IDE drives now if not disabled
751 # Notice: Already done by linuxrc, but make sure it's done also on harddisk-installed systems
752 config_dma(){
753 if checkbootparam 'nodma'; then
754   ewarn "Skipping DMA accelleration as requested on boot commandline." ; eend 0
755 else
756   for d in $(cd /proc/ide 2>>$DEBUG && echo hd[a-z]); do
757     if test -d /proc/ide/$d; then
758       if egrep -q 'using_dma[ \t]+0' /proc/ide/$d/settings 2>>$DEBUG; then
759         MODEL="$(cat /proc/ide/$d/model 2>>$DEBUG)"
760         test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]"
761         einfo "Enabling DMA acceleration for: ${WHITE}$d        ${YELLOW}[${MODEL}]${NORMAL}"
762         echo "using_dma:1" >/proc/ide/$d/settings
763         eend 0
764       fi
765     fi
766   done
767 fi
768 }
769 # }}}
770
771 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
772 config_fstab(){
773
774 NOSWAP="yes" # we do not use swap by default!
775 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
776    NOSWAP=''
777    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
778 fi
779
780 # Scan for swap, config, homedir - but only in live-mode
781 if [ -z "$INSTALLED" ] ; then
782    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
783    GRML_IMG=""
784    GRML_SWP=""
785    HOMEDIR="$(getbootparam 'home')"
786    if [ -n "$partitions" ]; then
787       while read p m f relax; do
788         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
789         partoptions="users,exec"
790         fnew=""
791         # it's a swap partition?
792         case "$f" in swap)
793           eindent
794           if [ -n "$NOSWAP" ]; then
795              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
796              eend 0
797           else
798              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
799                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
800                      if [ -n "$ANYSWAP" ] ; then
801                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
802                         swapon $p 2>>$DEBUG ; eend $?
803                      else
804                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
805                      fi
806                      ;;
807                    *)
808                      if [[ "$p" == LABEL* ]] ; then
809                         p=$(blkid -t $p | awk -F: '{print $1}')
810                      fi
811                      if grep -q $p /proc/swaps ; then
812                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
813                      else
814                         if [ -b "$p" ] ; then
815                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
816                         swapon $p 2>>$DEBUG ; eend $?
817                         else
818                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
819                         fi
820                      fi
821                      ;;
822              esac # dd-check
823           fi # -n "$NOSWAP
824           eoutdent
825           continue
826           ;;
827         esac # it's a swap partition?
828
829         # mount read-only
830         MOUNTOPTS="ro"
831         case "$f" in
832           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
833           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
834           *) continue ;;
835           # *) NONEFOUND='1'; continue ;;
836         esac
837
838         # use a swapfile
839         if [ -z "$NOSWAP" ] ; then
840            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
841            # Activate swapfile, if exists
842            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
843         fi
844         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
845            mount -o remount,rw $m && MOUNTED=1
846            if swapon "$SWAPFILE" 2>>$DEBUG ; then
847               eindent
848                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
849               eoutdent
850               fnew="$SWAPFILE swap swap defaults 0 0"
851               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
852               GRML_SWP="$GRML_SWP $SWAPFILE"
853               eend 0
854            fi
855            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
856         fi
857
858         # use a image as home
859         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
860         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
861            if [ -n "$HOMEDIR" ]; then
862               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
863                  continue
864               fi
865            fi
866            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
867               GRML_IMG="$IMAGE"
868               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
869            fi
870         fi
871         eend 0
872
873         # Umount, if not in use
874         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
875
876       done <<EOT
877       $(cat /etc/fstab)
878 EOT
879    fi # -n $partitions
880 fi # -z $INSTALLED
881 }
882 # }}}
883
884 # {{{ Mouse
885 config_mouse(){
886 if [ -n "$MOUSE_DEVICE" ] ; then
887   einfo "Detecting mouse: ${MOUSE_FULLNAME} at ${MOUSE_DEVICE}" ; eend $?
888 fi
889 }
890 # }}}
891
892 # {{{ IPv6 configuration
893 # Load IPv6 kernel module and print IP adresses
894 config_ipv6(){
895 if checkbootparam 'ipv6'; then
896   einfo "Enabling IPv6 as requested on boot commandline (sleeping for 2 seconds)"
897   modprobe ipv6
898   # we probably need some time until stateless autoconfiguration has happened
899   sleep 2
900   NETDEVICES="$(awk -F: '/eth.:|tr.:|wlan.:/{print $1}' /proc/net/dev 2>>$DEBUG)"
901   for DEVICE in `echo "$NETDEVICES"`; do
902     eindent
903       einfo "$DEVICE:"
904       ADDRESSES="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{print $3}')"
905       COUNT="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{ sum += 1};END {print sum }')"
906       eindent
907         for ADDR in `echo "$ADDRESSES"` ; do
908             einfo "$ADDR"
909         done
910         if [ "$COUNT" -eq "0" ] ; then
911            einfo "(none)" ; eend 1
912         fi
913       eoutdent
914     eoutdent
915   done
916   eend 0
917 fi
918 }
919 # }}}
920
921 # {{{ CPU-detection
922 config_cpu(){
923 if checkbootparam 'nocpu'; then
924   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
925   return 0
926 fi
927
928 if [[ $(grep -c processor /proc/cpuinfo) -gt 1 ]] ; then
929    einfo "Detecting CPU:"
930    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)
931    echo $CPU | sed 's/ \{1,\}/ /g'
932    eend 0
933 else
934    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
935 fi
936
937 # no cpufreq setup inside VirtualBox
938 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
939    einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0
940    return 0
941 fi
942
943 if [ -x /etc/init.d/loadcpufreq ] ; then
944    einfo "Trying to set up cpu frequency scaling:"
945    eindent
946    SKIP_CPU_GOVERNOR=''
947    LOADCPUFREQ=$(mktemp)
948    /etc/init.d/loadcpufreq start >"$LOADCPUFREQ" 2>&1 ; RC=$?
949    if grep -q FATAL "$LOADCPUFREQ" ; then
950       eindent
951         SKIP_CPU_GOVERNOR=1
952         oldIFS="$IFS"
953         IFS="
954 "
955          for line in $(grep FATAL "$LOADCPUFREQ" | sed 's/.*FATAL: //; s/ (.*)//') ; do
956              eerror "$line" ; eend $RC
957          done
958          IFS="$oldIFS"
959       eoutdent
960    elif grep -q done "$LOADCPUFREQ" ; then
961       MODULE=$(grep done "$LOADCPUFREQ" | sed 's/.*done (\(.*\))./\1/')
962       if [ -n "$MODULE" -a "$MODULE" != none ]; then
963          einfo "Loading cpufreq kernel module $MODULE" ; eend 0
964       else
965          ewarn "Could not find an appropriate kernel module for cpu frequency scaling." ; eend 1
966       fi
967    fi
968
969    rm -f $LOADCPUFREQ
970
971    if [ -z "$SKIP_CPU_GOVERNOR" ] ; then
972       einfo "Loading cpufreq_ondemand, setting ondemand governor"
973       RC=0
974       if modprobe cpufreq_ondemand ; RC=$? ; then
975          for file in $(find /sys/devices/system/cpu/ -name scaling_governor 2>/dev/null) ; do
976             echo ondemand > $file
977          done
978       fi
979       eend $RC
980    fi # cpu-governor
981
982    eoutdent
983 fi
984 }
985 # }}}
986
987 # {{{ autostart of ssh
988 config_ssh(){
989 if checkbootparam 'ssh' ; then
990    SSH_PASSWD=''
991    SSH_PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
992    einfo "Bootoption ssh found, trying to set password for user grml."
993    eindent
994    if [ -z "$SSH_PASSWD" ] ; then
995       if [ -x /usr/bin/apg ] ; then
996          SSH_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
997       elif [ -x /usr/bin/gpw ] ; then
998          SSH_PASSWD="$(gpw 1)"
999       elif [ -x /usr/bin/pwgen ] ; then
1000          SSH_PASSWD="$(pwgen -1 8)"
1001       elif [ -x /usr/bin/hexdump ] ; then
1002          SSH_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1003       elif [ -n "$RANDOM" ] ; then
1004          SSH_PASSWD="grml${RANDOM}"
1005       else
1006          SSH_PASSWD=''
1007          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1008          eend 1
1009       fi
1010
1011       if [ -n "$SSH_PASSWD" ] ; then
1012          ewarn "No given password for ssh found. Using random password: $SSH_PASSWD" ; eend 0
1013       fi
1014    fi
1015    eoutdent
1016
1017    # finally check if we have a password we can use:
1018    if [ -n "$SSH_PASSWD" ] ; then
1019       # chpasswd sucks, seriously.
1020       if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1021         echo "grml:$SSH_PASSWD" | chpasswd -m
1022       else
1023         echo "grml:$SSH_PASSWD" | chpasswd
1024       fi
1025    fi
1026
1027    einfo 'Starting secure shell server in background.'
1028    /etc/init.d/rmnologin start >>$DEBUG 2>>$DEBUG
1029    /etc/init.d/ssh start >>$DEBUG 2>>$DEBUG &
1030    eend $?
1031
1032    eindent
1033    ewarn 'Warning: please change the password for user grml as soon as possible!'
1034    eoutdent
1035 fi
1036 }
1037 # }}}
1038
1039 # {{{ autostart of x11vnc
1040 config_vnc(){
1041
1042 USER=grml # TODO: make it dynamically configurable
1043 if checkbootparam 'vnc' ; then
1044    VNC_PASSWD=''
1045    VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)"
1046    einfo "Bootoption vnc found, trying to set password for user $USER."
1047    eindent
1048    if [ -z "$VNC_PASSWD" ] ; then
1049       if [ -x /usr/bin/apg ] ; then
1050          VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1051       elif [ -x /usr/bin/gpw ] ; then
1052          VNC_PASSWD="$(gpw 1)"
1053       elif [ -x /usr/bin/pwgen ] ; then
1054          VNC_PASSWD="$(pwgen -1 8)"
1055       elif [ -x /usr/bin/hexdump ] ; then
1056          VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1057       elif [ -n "$RANDOM" ] ; then
1058          VNC_PASSWD="${USER}${RANDOM}"
1059       else
1060          VNC_PASSWD=''
1061          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1062          eend 1
1063       fi
1064
1065       if [ -n "$VNC_PASSWD" ] ; then
1066          ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0
1067       fi
1068    fi
1069    eoutdent
1070
1071    # finally check if we have a password we can use:
1072    if [ -n "$VNC_PASSWD" ] ; then
1073
1074       VNCDIR="/home/${USER}/.vnc"
1075       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1076
1077       if [ ! -x /usr/bin/x11vnc ] ; then
1078          eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package."
1079          eend 1
1080       else
1081          /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $?
1082          /bin/chown -R "$USER": "$VNCDIR"
1083       fi
1084    fi
1085    if checkbootparam 'vnc_connect' ; then
1086       VNC_CONNECT=''
1087       VNC_CONNECT="$(getbootparam 'vnc_connect' 2>>$DEBUG)"
1088       einfo "Bootoption vnc_connect found, will start vnc with connect to $VNC_CONNECT."
1089       #store the options in a file
1090       VNCDIR="/home/${USER}/.vnc"
1091       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1092       echo " --connect $VNC_CONNECT " >> $VNCDIR/options
1093    fi
1094 fi
1095 }
1096 # }}}
1097
1098 # {{{ set password for user grml
1099 config_passwd(){
1100 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1101   einfo "Bootoption passwd found."
1102   PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1103   if [ -n "$PASSWD" ] ; then
1104     echo "grml:$PASSWD" | chpasswd -m ; eend $?
1105   else
1106     eerror "No given password for ssh found. Autostart of SSH will not work." ; eend 1
1107   fi
1108   eindent
1109     ewarn "Warning: please change the password for user grml set via bootparameter as soon as possible!"
1110   eoutdent
1111 fi
1112 }
1113 # }}}
1114
1115 # {{{ Sound
1116 config_mixer () {
1117    if ! [ -x /usr/bin/amixer ] ; then
1118       eerror "amixer binary not available. Can not set sound volumes therefore."
1119       eend 1
1120    else
1121       if ! [ -r /proc/asound/cards ] ; then
1122          ewarn "No soundcard present, skipping mixer settings therefore."
1123          eend 0
1124          return
1125       fi
1126
1127       for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do
1128          einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\""
1129          eindent
1130
1131          if checkbootparam 'vol' ; then
1132             VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1133             if [ -z "$VOL" ] ; then
1134                eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)."
1135                VOL='75'
1136                eend 1
1137             fi
1138          else
1139             VOL='75'
1140          fi
1141
1142          if checkbootparam 'nosound' ; then
1143             einfo "Muting sound devices on request."
1144             ERROR=$(amixer -q set Master mute)
1145             RC=$?
1146             if [ -n "$ERROR" ] ; then
1147                eindent
1148                eerror "Problem muting sound devices: $ERROR"
1149                eoutdent
1150             fi
1151             eend $RC
1152          elif [ -z "$INSTALLED" ] ; then
1153             einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1154
1155             if checkbootparam 'micvol' ; then
1156                MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1157             else
1158                MICVOL=0
1159             fi
1160
1161             for CONTROL in Master PCM ; do
1162                if amixer -q | grep -q "Simple mixer control '$CONTROL'" ; then
1163                   amixer -q set "${CONTROL}" "${VOL}"%
1164                   eend $?
1165                fi
1166             done
1167
1168             if [ ${MICVOL} -ne 0 ] ; then
1169                einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1170                amixer -q set "Mic" $MICVOL &> /dev/null
1171                eend $?
1172             fi
1173          fi # checkbootparam 'nosound'
1174          eoutdent
1175       done
1176    fi
1177 }
1178 # }}}
1179
1180 # {{{ modem detection
1181 config_modem(){
1182 if checkbootparam 'nomodem'; then
1183   ewarn "Skipping check for AC97 modem controller as requested on boot commandline." ; eend 0
1184 else
1185   if [ -x /etc/init.d/sl-modem-daemon ] ; then
1186      if lspci | grep Intel | grep -q "AC'97 Modem Controller" ; then
1187         einfo "AC97 modem controller detected. Start it running 'Start sl-modem-daemon'."
1188         eend 0
1189      fi
1190   fi
1191 fi
1192 }
1193 # }}}
1194
1195 # {{{ wondershaper
1196 config_wondershaper(){
1197  if checkbootparam 'wondershaper' ; then
1198     WONDER="$(getbootparam 'wondershaper' 2>>$DEBUG)"
1199     CMD=wondershaper
1200     DEVICE=""
1201     DOWNSTREAM=""
1202     UPSTREAM=""
1203     if [ -n "$WONDER" ]; then
1204       # Extra options
1205       DEVICE="${WONDER%%,*}"
1206       R="${WONDER#*,}"
1207       if [ -n "$R" -a "$R" != "$WONDER" ]; then
1208         WONDER="$R"
1209         DOWNSTREAM="${WONDER%%,*}"
1210         R="${WONDER#*,}"
1211         if [ -n "$R" -a "$R" != "$WONDER" ]; then
1212           WONDER="$R"
1213           UPSTREAM="${WONDER%%,*}"
1214           R="${WONDER#*,}"
1215         fi
1216       fi
1217     fi
1218     [ -n "$DEVICE" ]     && CMD="$CMD $DEVICE"
1219     [ -n "$DOWNSTREAM" ] && CMD="$CMD $DOWNSTREAM"
1220     [ -n "$UPSTREAM" ]   && CMD="$CMD $UPSTREAM"
1221     einfo "Starting wondershaper (${CMD}) in background."
1222     ( sh -c $CMD & ) && eend 0
1223  fi
1224 }
1225 # }}}
1226
1227 # {{{ syslog-ng
1228 config_syslog(){
1229  if checkbootparam 'nosyslog'; then
1230     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1231  else
1232     SYSLOGD=''
1233     [ -x /etc/init.d/syslog-ng ] && SYSLOGD='syslog-ng'
1234     [ -x /etc/init.d/rsyslog   ] && SYSLOGD='rsyslog'
1235     [ -x /etc/init.d/dsyslog   ] && SYSLOGD='dsyslog'
1236     [ -x /etc/init.d/sysklogd  ] && SYSLOGD='sysklogd'
1237     [ -x /etc/init.d/inetutils-syslogd ] && SYSLOGD='inetutils-syslogd'
1238
1239     if [ -z "$SYSLOGD" ] ; then
1240        eerror "No syslog daemon found." ; eend 1
1241     else
1242        einfo "Starting $SYSLOGD in background."
1243        /etc/init.d/$SYSLOGD start >>$DEBUG &
1244        eend 0
1245     fi
1246  fi
1247 }
1248 # }}}
1249
1250 # {{{ gpm
1251 config_gpm(){
1252  if checkbootparam 'nogpm'; then
1253   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1254  else
1255    if ! [ -r /dev/input/mice ] ; then
1256       eerror "No mouse found - not starting GPM." ; eend 1
1257    else
1258       einfo "Starting gpm in background."
1259       /etc/init.d/gpm start >>$DEBUG &
1260       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start >>$DEBUG ) &
1261       eend 0
1262    fi
1263  fi
1264 }
1265 # }}}
1266
1267 # {{{ services
1268 config_services(){
1269  if checkbootparam 'services' ; then
1270     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1271     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1272     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1273     for service in $(echo -e $SERVICELIST) ; do
1274       # support running (custom) init scripts in non-blocking mode
1275       # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1276       if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1277         einfo "Starting service ${service}."
1278         /etc/init.d/${service} start >>$DEBUG
1279       else
1280         einfo "Starting service ${service} in background."
1281         /etc/init.d/${service} start >>$DEBUG &
1282       fi
1283     done
1284     eend $?
1285  fi
1286 }
1287 # }}}
1288
1289 # {{{ remote files
1290 get_remote_file() {
1291   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1292   SOURCE=$(eval echo "$1")
1293   TARGET="$2"
1294   getconfig() {
1295   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1296        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1297   }
1298   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1299   counter=10
1300   while ! getconfig && [[ "$counter" != 0 ]] ; do
1301     echo -n "Sleeping for 1 second and trying to get config again... "
1302     counter=$(( counter-1 ))
1303     echo "$counter tries left" ; sleep 1
1304   done
1305   if [ -s "$TARGET" ] ; then
1306     einfo "Downloading was successfull." ; eend 0
1307     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1308     md5sum ${TARGET} ; eend 0
1309     return 0;
1310   else
1311     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1312     return 1;
1313  fi
1314 }
1315 # }}}
1316
1317 # {{{ config files
1318 config_netconfig(){
1319  if checkbootparam 'netconfig' ; then
1320   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1321   CONFIGFILE='/tmp/netconfig.grml'
1322
1323   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1324     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1325   fi
1326
1327  fi
1328 }
1329 # }}}
1330
1331 # {{{ remote scripts
1332 config_netscript() {
1333  if checkbootparam 'netscript' ; then
1334   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1335   SCRIPTFILE='/tmp/netscript.grml'
1336
1337   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1338     chmod +x ${SCRIPTFILE}
1339     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1340   fi
1341
1342  fi
1343 }
1344 # }}}
1345
1346 # {{{ fix/workaround for unionfs
1347 fix_unionfs(){
1348   if [ -z "$INSTALLED" ]; then
1349    touch /var/cache/apt/*cache.bin
1350   fi
1351 }
1352 # }}}
1353
1354 # {{{ start X window system via grml-x
1355 config_x_startup(){
1356 # make sure we start X only if startx is used *before* a nostartx option
1357 # so it's possible to disable automatic X startup using nostart
1358 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1359  if [ -x "$(which X)" ] ; then
1360   if [ -z "$INSTALLED" ] ; then
1361    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1362    if [ -z "$WINDOWMANAGER" ] ; then
1363      einfo "No window manager specified. Taking ${WHITE}wm-ng${NORMAL} as default." && eend 0
1364      WINDOWMANAGER="wm-ng"
1365    else
1366      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1367    fi
1368    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1369    config_userfstab || fstabuser='grml'
1370  cat>|/etc/init.d/xstartup<<EOF
1371 #!/bin/sh
1372 su $fstabuser -c "/usr/bin/grml-x $WINDOWMANAGER"
1373 EOF
1374    chmod 755 /etc/init.d/xstartup
1375
1376    # adjust inittab for xstartup
1377    if grep -q '^6:' /etc/inittab ; then
1378       sed -i 's|^6:.*|6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/share/grml-scripts/run-welcome" >/dev/tty6 2>\&1 </dev/tty6|' /etc/inittab
1379    else # just append tty6 to inittab if no definition is present:
1380       echo '6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/share/grml-scripts/run-welcome" >/dev/tty6 2>&1 < /dev/tty6' >> /etc/inittab
1381    fi
1382
1383    /sbin/telinit q ; eend $?
1384
1385    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1386       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1387    else
1388       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1389    fi
1390
1391   else
1392     eerror "We are not running in live mode - startx will not work, skipping it."
1393     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1394   fi
1395  else
1396    eerror "/usr/X11R6/bin/X is not present on this grml flavour."
1397    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1398  fi
1399 fi
1400 }
1401 # }}}
1402
1403 # {{{ configuration framework
1404 config_extract(){
1405 if checkbootparam 'extract' ; then
1406  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1407  EXTRACTOPTIONS="-- -x $EXTRACT"
1408 fi
1409 }
1410
1411 config_finddcsdir() {
1412 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1413 #    on the command line, nothing is changed and the dcs files are
1414 #    searched within the .iso, $dcs-dir is set to the root directory
1415 #    within the .iso
1416 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1417 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1418 #    set, $dcs-dir is set to the root directory within the .iso.
1419 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1420 #    foo, even if a GRMLCFG partition is present.
1421 DCSDIR=""
1422 DCSMP="/mnt/grml"
1423 # autoconfig, see issue673
1424 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1425 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1426 if checkbootparam 'noautoconfig' || checkbootparam 'forensic' ; then
1427   ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1428 else
1429   if [ -z "$INSTALLED" ] ; then
1430     if checkbootparam 'myconfig' ; then
1431       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1432       if [ -z "$DCSDEVICE" ]; then
1433         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1434       fi # [ -z "$DCSDEVICE" ]
1435     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1436       einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1437       eindent
1438       # We do need the following fix so floppy disk is available to blkid in any case :-/
1439       if [ -r /dev/fd0 ] ; then
1440         einfo "Floppy device detected. Trying to access floppy disk."
1441         if timeout 4 dd if=/dev/fd0 of=/dev/null bs=512 count=1 >>$DEBUG 2>&1 ; then
1442            blkid /dev/fd0 >>$DEBUG 2>&1
1443         fi
1444       fi
1445       DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1446       if [ -n "$DCSDEVICE" ]; then
1447         DCSMP="/mnt/grmlcfg"
1448       fi
1449       eoutdent
1450     fi
1451
1452     # if not specified/present then assume default:
1453     if [ -z "$DCSDEVICE" ]; then
1454       DCSDIR="/live/image"
1455     else
1456       eindent
1457       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1458       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1459       if [ -n "$DCSDIR" ]; then
1460         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1461       else
1462         [ -d $DCSMP ] || mkdir $DCSMP
1463         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1464         mount -o ro -t auto $DCSDEVICE  $DCSMP ; RC="$?"
1465         if [[ $RC == 0 ]]; then
1466           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1467         else
1468           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1469         fi
1470         DCSDIR="$DCSMP"
1471       fi
1472       eoutdent
1473     fi
1474   fi
1475 fi
1476
1477 if [ -n "$DCSDIR" -a "$DCSDIR" != "/live/image" ] ; then
1478   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1479 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1480   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1481 fi
1482 }
1483
1484
1485 config_partconf() {
1486 if checkbootparam 'partconf' ; then
1487  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1488  if [ -n "$MOUNTDEVICE" ]; then
1489    [ -d /mnt/grml ] || mkdir /mnt/grml
1490    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1491     if [[ $RC == 0 ]]; then
1492       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1493       einfo "Copying files from $MOUNTDEVICE over grml system."
1494       for file in `cat /etc/grml/partconf` ; do
1495         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1496         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1497       done && eend 0
1498     else
1499       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1500     fi # mount $MOUNTDEVICE
1501    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1502  else
1503    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1504  fi # [ -n "$MOUNTDEVICE" ]
1505 fi
1506 }
1507 # }}}
1508
1509 # {{{ /cdrom/.*-options
1510 config_debs(){
1511 if checkbootparam 'debs' ; then
1512    iszsh && setopt localoptions shwordsplit
1513    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1514    if [ -z "$DEBS" ] ; then
1515       DEBS="*.deb"
1516    fi
1517    if ! echo $DEBS | grep -q '/'; then
1518      # backwards compatibility: if no path is given get debs from debs/
1519      DEBS="debs/$DEBS"
1520    fi
1521    einfo "Tring to install debian package(s) ${DEBS}"
1522    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1523    dpkg -i $DEBS ; eend $?
1524 fi
1525 }
1526
1527 config_scripts(){
1528 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1529    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1530    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1531      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1532    fi
1533    if ! echo $SCRIPTS | grep -q '/'; then
1534      # backwards compatibility: if no path is given get scripts from scripts/
1535      SCRIPTS="scripts/$SCRIPTS"
1536    fi
1537    if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1538      # we are executing from a GRMLCFG labeled fs
1539      # kick everything we have done before and start over
1540      SCRIPTS="$(cd ${DCSDIR}; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1541    fi
1542    if [ -n "$SCRIPTS" ]; then
1543      SCRIPTS="${DCSDIR}/$SCRIPTS"
1544      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1545        einfo "Trying to execute ${SCRIPTS}"
1546        sh -c $SCRIPTS
1547      elif [ -d "$SCRIPTS" ]; then
1548        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1549        run-parts $SCRIPTS
1550      else
1551        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1552        sh -c $SCRIPTS
1553      fi
1554    fi
1555 fi
1556 }
1557
1558 config_config(){
1559 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1560   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1561   if [ -z "$CONFIG" ]; then
1562     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1563   fi
1564   if [ -n "$CONFIG" ]; then
1565     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1566       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1567
1568       cp -a ${DCSDIR}/${CONFIG}/* /
1569     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1570       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1571
1572       cd /
1573       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1574     else
1575       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1576     fi
1577   fi
1578 fi
1579 }
1580 # }}}
1581
1582 # {{{ confing_umount_dcsdir
1583 config_umount_dcsdir(){
1584    # umount $DCSMP if it was mounted by finddcsdir
1585    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1586 }
1587 # }}}
1588
1589 # {{{ mypath
1590 config_mypath(){
1591 if checkbootparam 'mypath' ; then
1592    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1593    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1594    touch /etc/grml/my_path
1595    chmod 644 /etc/grml/my_path
1596    # make sure the directories exist:
1597    eindent
1598    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1599        if ! [ -d "$i" ] ; then
1600           einfo "Creating directory $i"
1601           mkdir -p "$i" ; eend $?
1602        fi
1603    done
1604    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1605    eoutdent
1606 fi
1607 }
1608 # }}}
1609
1610 # {{{ distcc
1611 config_distcc(){
1612 if checkbootparam 'distcc' ; then
1613  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
1614  if [ -n "$OPTIONS" ]; then
1615     NET=""
1616     INTERFACE=""
1617     if [ -n "$OPTIONS" ]; then
1618       NET="${OPTIONS%%,*}"
1619       R="${OPTIONS#*,}"
1620       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1621         OPTIONS="$R"
1622         INTERFACE="${OPTIONS%%,*}"
1623         R="${OPTIONS#*,}"
1624       fi
1625     fi
1626  fi
1627  CONFIG=/etc/default/distcc
1628  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
1629  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
1630
1631  if [ -n "$INTERFACE" ] ; then
1632    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1633
1634    counter=10
1635    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
1636      counter=$(( counter-1 ))
1637      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
1638      sleep 3
1639      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1640    done
1641  fi
1642
1643  if [ -n "$IP" ] ; then
1644    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
1645
1646    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
1647    eindent
1648     id distccd >/dev/null 2>&1 || \
1649     (
1650       einfo "Creating distcc user" ; \
1651       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
1652     )
1653
1654     einfo "Starting distcc for network ${NET}, listening on ${IP}."
1655    /etc/init.d/distcc start >/dev/null ; eend $?
1656    eoutdent
1657  else
1658    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
1659  fi
1660 fi
1661
1662 if checkbootparam 'gcc'; then
1663  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
1664  eindent
1665  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
1666  eoutdent
1667  rm -f /usr/bin/gcc
1668  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
1669 fi
1670
1671 if checkbootparam 'gpp'; then
1672  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
1673  eindent
1674   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
1675   if [ -x /usr/bin/g++-${GPP} ] ; then
1676      rm -f /usr/bin/g++
1677      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
1678   fi
1679   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
1680   if [ -x /usr/bin/cpp-${GPP} ] ; then
1681      rm -f /usr/bin/cpp
1682      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
1683   fi
1684  eoutdent
1685 fi
1686
1687 }
1688 # }}}
1689
1690 # {{{ load modules
1691 # Notice: use it only on live-cd system, if running from harddisk please
1692 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
1693 # in /etc/runlevel.conf
1694 config_modules(){
1695 MODULES_FILE=/etc/grml/modules
1696 if checkbootparam 'nomodules' ; then
1697   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
1698 elif [ -z "$INSTALLED" ]; then
1699  if [ -r $MODULES_FILE ] ; then
1700   einfo "Loading modules specified in ${MODULES_FILE}:"
1701   eindent
1702   grep '^[^#]' $MODULES_FILE | \
1703   while read module args; do
1704     [ "$module" ] || continue
1705       einfo "${module}"
1706       modprobe $module $args ; eend $?
1707   done
1708   eoutdent
1709  else
1710   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
1711  fi
1712 fi
1713 }
1714 # }}}
1715
1716 # {{{ 915resolution
1717 config_915resolution(){
1718 if checkbootparam '915resolution' ; then
1719  OPTIONS="$(getbootparam '915resolution' 2>>$DEBUG)"
1720   if [ -x /usr/sbin/915resolution ]; then
1721     CMD=915resolution
1722     MODE=""
1723     XRESO=""
1724     YRESO=""
1725     if [ -n "$OPTIONS" ]; then
1726       # Extra options
1727       MODE="${OPTIONS%%,*}"
1728       R="${OPTIONS#*,}"
1729       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1730         OPTIONS="$R"
1731         XRESO="${OPTIONS%%,*}"
1732         R="${OPTIONS#*,}"
1733         if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1734           OPTIONS="$R"
1735           YRESO="${OPTIONS%%,*}"
1736           R="${OPTIONS#*,}"
1737         fi
1738       fi
1739     fi
1740     einfo "Running 915resolution with options ${MODE} ${XRESO} ${YRESO}."
1741     [ -n "$MODE" ] && [ -n "$XRESO"  ] && [ -n "$YRESO" ]  && ( sh -c "$CMD $MODE $XRESO $YRESO" & )
1742     eend 0
1743   fi
1744 fi
1745 }
1746 # }}}
1747
1748 # {{{ SW-RAID
1749 config_swraid(){
1750   [ -n "$INSTALLED" ] && return 0
1751
1752   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
1753   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1754      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
1755      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1756   else
1757     if ! [ -x /sbin/mdadm ] ; then
1758        eerror "mdadm not available, can not execute it." ; eend 1
1759     else
1760
1761        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1762        # find out whether we have a valid configuration file already
1763        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1764           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1765           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1766           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1767         else
1768           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1769        fi
1770
1771        if ! checkbootparam 'swraid' ; then
1772           eindent
1773           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1774           eoutdent
1775        else
1776           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1777           eindent
1778            IFSOLD=${IFS:-}
1779            IFS='
1780 '
1781            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
1782                case $line in
1783                  *'No arrays found'*)
1784                    ewarn "$line" ; eend 0
1785                    ;;
1786                  *)
1787                    einfo "$line" ; eend 0
1788                    ;;
1789                esac
1790            done
1791            IFS=$IFSOLD
1792          eoutdent
1793
1794          if [ -r /proc/mdstat ] ; then
1795             eindent
1796             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1797             if [ -z "$MDSTAT" ] ; then
1798                ewarn "No active arrays found" ; eend 0
1799             else
1800                IFSOLD=${IFS:-}
1801                IFS='
1802 '
1803                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1804                    einfo "active arrays: $line" ; eend 0
1805                done
1806                IFS=$IFSOLD
1807             fi
1808             eoutdent
1809          fi # /proc/mdstat
1810        fi # bootoption swraid
1811
1812      fi # is /sbin/mdadm executable?
1813   fi # check for bootoptions
1814 }
1815 # }}}
1816
1817 # {{{ dmraid
1818 config_dmraid(){
1819   [ -n "$INSTALLED" ] && return 0
1820
1821   if checkbootparam 'nodmraid' ; then
1822     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1823     return 0
1824   fi
1825
1826   if ! [ -x /sbin/dmraid ] ; then
1827     eerror "dmraid not available, can not execute it." ; eend 1
1828     return
1829   fi
1830
1831   dmraid_wrapper() {
1832     # usage: dmraid_wrapper <dmraid_option>
1833     [ -n "$1" ] || return 1
1834
1835     IFSOLD=${IFS:-}
1836     IFS='
1837 '
1838     eindent
1839
1840     for line in $(dmraid $1 ; echo errcode:$?); do
1841       case $line in
1842         *'no block devices found'*)
1843           einfo "No block devices found" ; eend 0
1844           break
1845           ;;
1846         *'no raid disks'*)
1847           einfo "No active dmraid devices found" ; eend 0
1848           break
1849           ;;
1850         errcode:0)
1851           eend 0;
1852           ;;
1853         errcode:1)
1854           eend 1
1855           ;;
1856         *)
1857           einfo "$line"
1858           ;;
1859       esac
1860     done
1861
1862     eoutdent
1863     IFS=$IFSOLD
1864   }
1865
1866   if checkbootparam 'dmraid' ; then
1867     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1868     if [ "$ACTION" = "off" ] ; then
1869       # Deactivates all active software RAID sets:
1870       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1871       dmraid_wrapper -an
1872     else
1873       # Activate all software RAID sets discovered:
1874       einfo "Activating present dmraid sets (as requested via dmraid):"
1875       dmraid_wrapper -ay
1876     fi
1877
1878     return
1879   fi
1880
1881   # by default (no special bootoptions) discover all software RAID devices:
1882   einfo "Searching for any present dmraid sets:"
1883   dmraid_wrapper -r
1884 }
1885 # }}}
1886
1887 # {{{ LVM (Logical Volumes)
1888 config_lvm(){
1889   [ -n "$INSTALLED" ] && return 0
1890
1891   if checkbootparam 'nolvm' ; then
1892      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1893   else
1894     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
1895     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
1896        eerror "LVM not available, can not execute it." ; eend 1
1897     else
1898        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1899           einfo "You seem to have logical volumes (LVM) on your system."
1900           eindent
1901           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1902           eend 0
1903           if checkbootparam 'lvm' ; then
1904              einfo "Bootoption LVM found. Searching for logical volumes:"
1905              /etc/init.d/lvm2 start ; eend $?
1906           fi
1907           eoutdent
1908        fi
1909     fi # check for lvm binary
1910   fi # check for bootoption nolvm
1911 }
1912 # }}}
1913
1914 # {{{ debnet: setup network based on an existing one found on a partition
1915 config_debnet(){
1916 if checkbootparam 'debnet' ; then
1917  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1918  /usr/sbin/debnet
1919 fi
1920 }
1921 # }}}
1922
1923 # {{{ disable console blanking
1924 config_blanking(){
1925 if checkbootparam 'noblank' ; then
1926   einfo "Bootoption noblank found. Disabling monitor blanking."
1927   setterm -blank 0 ; eend $?
1928 fi
1929 }
1930 # }}}
1931
1932 # {{{ tohd= bootoption
1933 config_tohd()
1934 {
1935   if checkbootparam 'tohd' ; then
1936      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
1937      if [ -z "$TARGET" ] ; then
1938         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
1939         eerror "Please use something like tohd=/dev/sda9." ; eend 1
1940         return 1
1941      fi
1942
1943      if ! [ -b "$TARGET" ] ; then
1944         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
1945         return 1
1946      fi
1947
1948      if grep -q $TARGET /proc/mounts ; then
1949         eerror "$TARGET already mounted, skipping execution of tohd therefore."
1950         eend 1
1951         return 1
1952      fi
1953
1954      local MOUNTDIR=$(mktemp -d)
1955
1956      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
1957         einfo "Copyring live system to $TARGET - this might take a while"
1958         rsync -a --progress /live/image/live $MOUNTDIR
1959         sync
1960         umount "$MOUNTDIR"
1961         eend $?
1962         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
1963      else
1964         eerror "Error when trying to mount $TARGET, sorry."; eend 1
1965         return 1
1966      fi
1967
1968      rmdir "$MOUNTDIR"
1969   fi
1970 }
1971 # }}}
1972
1973 # {{{ debootstrap: automatic installation
1974 config_debootstrap(){
1975
1976 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
1977
1978 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
1979
1980 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
1981    eindent
1982    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
1983    eoutdent
1984    exit 1
1985 fi
1986
1987 if checkbootparam 'target' ; then
1988   TARGET=''
1989   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
1990   # notice: the following checks whether the given partition is available, if not the skip
1991   # execution of grml-debootstrap as it might result in data loss...
1992   if ! [ -r "$TARGET" ] ; then
1993      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
1994   fi
1995 else
1996   eindent
1997   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
1998   eoutdent
1999   exit 1
2000 fi
2001
2002 if checkbootparam 'grub' ; then
2003   GRUB=''
2004   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2005 fi
2006
2007 if checkbootparam 'groot' ; then
2008   GROOT=''
2009   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2010 fi
2011
2012 if checkbootparam 'release' ; then
2013   RELEASE=''
2014   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2015 fi
2016
2017 if checkbootparam 'mirror' ; then
2018   MIRROR=''
2019   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2020 fi
2021
2022 if checkbootparam 'boot_append' ; then
2023   BOOT_APPEND=''
2024   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2025 fi
2026
2027 if checkbootparam 'password' ; then
2028   PASSWORD=''
2029   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2030 fi
2031
2032 # now check which options are available
2033 if [ -n "TARGET" ] ; then
2034    TARGETCMD="--target $TARGET"
2035 else
2036    TARGETCMD=''
2037    eindent
2038    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2039    eoutdent
2040    exit 1
2041 fi
2042 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2043 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2044 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2045 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2046 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2047 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2048
2049 # and finally write script and execute it
2050 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2051 #!/bin/sh
2052 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2053 EOF
2054
2055 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2056
2057 screen /usr/bin/grml-debootstrap_noninteractive
2058 einfo "Invoking a shell, just exit to continue booting..."
2059 /bin/zsh
2060
2061 fi # checkbootparam "BOOT_IMAGE=debian2hd
2062 }
2063 # }}}
2064
2065 config_virtualbox_shared_folders() {
2066 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
2067   einfo "VirtualBox detected, trying to set up Shared Folders."
2068   if ! modprobe -l | grep -q vboxsf.ko ; then
2069     ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
2070     eend 0
2071   elif ! [ -x /usr/sbin/VBoxService ] ; then
2072     ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
2073     eend 0
2074   else
2075     eindent
2076
2077       einfo "Loading vboxsf driver."
2078       lsmod | grep -q vboxsf || modprobe vboxsf
2079       eend $?
2080
2081       einfo "Adjusting /dev/vboxguest."
2082       chown root:vboxsf /dev/vboxguest
2083       chmod 660 /dev/vboxguest
2084       eend $?
2085
2086       if [ -n "$CONFIG_FSTAB_USER" ] ; then
2087         fstabuser="$CONFIG_FSTAB_USER"
2088       else
2089         fstabuser=$(getent passwd 1000 | cut -d: -f1)
2090       fi
2091       einfo "Adding $fstabuser to group vboxsf."
2092       adduser grml vboxsf &>/dev/null
2093       eend $?
2094
2095       einfo "Starting VBoxService."
2096       VBoxService >/dev/null &
2097       eend $?
2098
2099     eoutdent
2100   fi
2101 fi
2102 }
2103
2104 # {{{ Support customization
2105 config_distri(){
2106 if checkbootparam 'distri'; then
2107   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2108   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2109      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2110      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2111      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2112      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2113   fi
2114 fi
2115 }
2116 # }}}
2117
2118 ## END OF FILE #################################################################
2119 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3