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