Automatically try to mount configfs
[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             else
1170                MICVOL=0
1171             fi
1172
1173             for CONTROL in Master PCM Front ; do
1174                if amixer -q | grep -q "Simple mixer control '$CONTROL'" ; then
1175                   amixer -q set "${CONTROL}" unmute 1>/dev/null 2>&1
1176                   amixer -q set "${CONTROL}" "${VOL}"%
1177                   eend $?
1178                fi
1179             done
1180
1181             if [ ${MICVOL} -ne 0 ] ; then
1182                einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1183                amixer -q set "Mic" $MICVOL &> /dev/null
1184                eend $?
1185             fi
1186          fi # checkbootparam 'nosound'
1187          eoutdent
1188       done
1189    fi
1190 }
1191 # }}}
1192
1193 # {{{ modem detection
1194 config_modem(){
1195 if checkbootparam 'nomodem'; then
1196   ewarn "Skipping check for AC97 modem controller as requested on boot commandline." ; eend 0
1197 else
1198   if [ -x /etc/init.d/sl-modem-daemon ] ; then
1199      if lspci | grep Intel | grep -q "AC'97 Modem Controller" ; then
1200         einfo "AC97 modem controller detected. Start it running 'Start sl-modem-daemon'."
1201         eend 0
1202      fi
1203   fi
1204 fi
1205 }
1206 # }}}
1207
1208 # {{{ wondershaper
1209 config_wondershaper(){
1210  if checkbootparam 'wondershaper' ; then
1211     WONDER="$(getbootparam 'wondershaper' 2>>$DEBUG)"
1212     CMD=wondershaper
1213     DEVICE=""
1214     DOWNSTREAM=""
1215     UPSTREAM=""
1216     if [ -n "$WONDER" ]; then
1217       # Extra options
1218       DEVICE="${WONDER%%,*}"
1219       R="${WONDER#*,}"
1220       if [ -n "$R" -a "$R" != "$WONDER" ]; then
1221         WONDER="$R"
1222         DOWNSTREAM="${WONDER%%,*}"
1223         R="${WONDER#*,}"
1224         if [ -n "$R" -a "$R" != "$WONDER" ]; then
1225           WONDER="$R"
1226           UPSTREAM="${WONDER%%,*}"
1227           R="${WONDER#*,}"
1228         fi
1229       fi
1230     fi
1231     [ -n "$DEVICE" ]     && CMD="$CMD $DEVICE"
1232     [ -n "$DOWNSTREAM" ] && CMD="$CMD $DOWNSTREAM"
1233     [ -n "$UPSTREAM" ]   && CMD="$CMD $UPSTREAM"
1234     einfo "Starting wondershaper (${CMD}) in background."
1235     ( sh -c $CMD & ) && eend 0
1236  fi
1237 }
1238 # }}}
1239
1240 # {{{ syslog-ng
1241 config_syslog(){
1242  if checkbootparam 'nosyslog'; then
1243     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1244  else
1245     SYSLOGD=''
1246     [ -x /etc/init.d/syslog-ng ] && SYSLOGD='syslog-ng'
1247     [ -x /etc/init.d/rsyslog   ] && SYSLOGD='rsyslog'
1248     [ -x /etc/init.d/dsyslog   ] && SYSLOGD='dsyslog'
1249     [ -x /etc/init.d/sysklogd  ] && SYSLOGD='sysklogd'
1250     [ -x /etc/init.d/inetutils-syslogd ] && SYSLOGD='inetutils-syslogd'
1251
1252     if [ -z "$SYSLOGD" ] ; then
1253        eerror "No syslog daemon found." ; eend 1
1254     else
1255        einfo "Starting $SYSLOGD in background."
1256        /etc/init.d/$SYSLOGD start >>$DEBUG &
1257        eend 0
1258     fi
1259  fi
1260 }
1261 # }}}
1262
1263 # {{{ gpm
1264 config_gpm(){
1265  if checkbootparam 'nogpm'; then
1266   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1267  else
1268    if ! [ -r /dev/input/mice ] ; then
1269       eerror "No mouse found - not starting GPM." ; eend 1
1270    else
1271       einfo "Starting gpm in background."
1272       /etc/init.d/gpm start >>$DEBUG &
1273       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start >>$DEBUG ) &
1274       eend 0
1275    fi
1276  fi
1277 }
1278 # }}}
1279
1280 # {{{ services
1281 config_services(){
1282  if checkbootparam 'services' ; then
1283     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1284     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1285     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1286     for service in $(echo -e $SERVICELIST) ; do
1287       # support running (custom) init scripts in non-blocking mode
1288       # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1289       if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1290         einfo "Starting service ${service}."
1291         /etc/init.d/${service} start >>$DEBUG
1292       else
1293         einfo "Starting service ${service} in background."
1294         /etc/init.d/${service} start >>$DEBUG &
1295       fi
1296     done
1297     eend $?
1298  fi
1299 }
1300 # }}}
1301
1302 # {{{ remote files
1303 get_remote_file() {
1304   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1305   SOURCE=$(eval echo "$1")
1306   TARGET="$2"
1307   getconfig() {
1308   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1309        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1310   }
1311   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1312   counter=10
1313   while ! getconfig && [[ "$counter" != 0 ]] ; do
1314     echo -n "Sleeping for 1 second and trying to get config again... "
1315     counter=$(( counter-1 ))
1316     echo "$counter tries left" ; sleep 1
1317   done
1318   if [ -s "$TARGET" ] ; then
1319     einfo "Downloading was successfull." ; eend 0
1320     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1321     md5sum ${TARGET} ; eend 0
1322     return 0;
1323   else
1324     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1325     return 1;
1326  fi
1327 }
1328 # }}}
1329
1330 # {{{ config files
1331 config_netconfig(){
1332  if checkbootparam 'netconfig' ; then
1333   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1334   CONFIGFILE='/tmp/netconfig.grml'
1335
1336   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1337     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1338   fi
1339
1340  fi
1341 }
1342 # }}}
1343
1344 # {{{ remote scripts
1345 config_netscript() {
1346  if checkbootparam 'netscript' ; then
1347   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1348   SCRIPTFILE='/tmp/netscript.grml'
1349
1350   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1351     chmod +x ${SCRIPTFILE}
1352     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1353   fi
1354
1355  fi
1356 }
1357 # }}}
1358
1359 # {{{ stats
1360 config_stats() {
1361  if ! checkbootparam 'nostats' ; then
1362    BASE_URL="http://stats.grml.org/report/"
1363    ACTION_NAME=Boot
1364
1365    HOST_ID=$(cat /proc/sys/kernel/random/boot_id)
1366
1367    grep -q " lm " /proc/cpuinfo && HAS_64BIT="1" || HAS_64BIT="0"
1368    DATE_STRING=$(date +'h=%H&m=%M&s=%S')
1369    [ -e /etc/grml_version ] && VERSION=$(cat /etc/grml_version) || \
1370      VERSION=$(lsb_release -d | awk -F: '{gsub(/^[ \t]+/, "", $2); print $2}')
1371
1372    PARAMS="$( echo "$CMDLINE" | sed -e 's/=[^ ]*/=x/g' | tr " " "\n"|sort|tr "\n" " " )"
1373
1374    echo "$CMDLINE" | grep -q -e "fetch" -e "nfsroot" && BOOT="remote"
1375    [ -z "$BOOT" ] && BOOT="local"
1376
1377    ADDITIONAL_PARAMS=""
1378    ( [ -n "$COLUMNS" ] && [ -n "$LINES" ] ) && \
1379      ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS&res=$((COLUMNS * 8))x$((LINES * 16))"
1380
1381    URI='$BASE_URL?action=${ACTION_NAME}\&$DATE_STRING\&unique_id=${HOST_ID}\&support_64bit=$HAS_64BIT\&version=$VERSION\&bootup=$BOOT\&params=$PARAMS$ADDITIONAL_PARAMS'
1382
1383    get_remote_file "$URI" "/dev/null"  >/dev/null 2>&1 &!
1384  fi
1385 }
1386 # }}}
1387 # {{{ fix/workaround for unionfs
1388 fix_unionfs(){
1389   if [ -z "$INSTALLED" ]; then
1390    touch /var/cache/apt/*cache.bin
1391   fi
1392 }
1393 # }}}
1394
1395 # {{{ start X window system via grml-x
1396 config_x_startup(){
1397 # make sure we start X only if startx is used *before* a nostartx option
1398 # so it's possible to disable automatic X startup using nostart
1399 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1400  if [ -x "$(which X)" ] ; then
1401   if [ -z "$INSTALLED" ] ; then
1402    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1403    if [ -z "$WINDOWMANAGER" ] ; then
1404      einfo "No window manager specified. Using default one." && eend 0
1405    else
1406      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1407    fi
1408    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1409    config_userfstab || fstabuser='grml'
1410  cat>|/etc/init.d/xstartup<<EOF
1411 #!/bin/sh
1412 su $fstabuser -c "/usr/bin/grml-x"
1413 EOF
1414    chmod 755 /etc/init.d/xstartup
1415
1416    # adjust inittab for xstartup
1417    if grep -q '^6:' /etc/inittab ; then
1418       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
1419    else # just append tty6 to inittab if no definition is present:
1420       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
1421    fi
1422
1423    /sbin/telinit q ; eend $?
1424
1425    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1426       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1427    else
1428       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1429    fi
1430
1431   else
1432     eerror "We are not running in live mode - startx will not work, skipping it."
1433     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1434   fi
1435  else
1436    eerror "/usr/bin/X is not present on this grml flavour."
1437    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1438  fi
1439 fi
1440 }
1441 # }}}
1442
1443 # {{{ configuration framework
1444 config_extract(){
1445 if checkbootparam 'extract' ; then
1446  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1447  EXTRACTOPTIONS="-- -x $EXTRACT"
1448 fi
1449 }
1450
1451 config_finddcsdir() {
1452 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1453 #    on the command line, nothing is changed and the dcs files are
1454 #    searched within the .iso, $dcs-dir is set to the root directory
1455 #    within the .iso
1456 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1457 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1458 #    set, $dcs-dir is set to the root directory within the .iso.
1459 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1460 #    foo, even if a GRMLCFG partition is present.
1461 DCSDIR=""
1462 DCSMP="/mnt/grml"
1463 # autoconfig, see issue673
1464 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1465 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1466 if checkbootparam 'noautoconfig' || checkbootparam 'forensic' ; then
1467   ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1468 else
1469   if [ -z "$INSTALLED" ] ; then
1470     if checkbootparam 'myconfig' ; then
1471       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1472       if [ -z "$DCSDEVICE" ]; then
1473         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1474       fi # [ -z "$DCSDEVICE" ]
1475     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1476       einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1477       eindent
1478       # We do need the following fix so floppy disk is available to blkid in any case :-/
1479       if [ -r /dev/fd0 ] ; then
1480         einfo "Floppy device detected. Trying to access floppy disk."
1481         if timeout 4 dd if=/dev/fd0 of=/dev/null bs=512 count=1 >>$DEBUG 2>&1 ; then
1482            blkid /dev/fd0 >>$DEBUG 2>&1
1483         fi
1484       fi
1485       DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1486       if [ -n "$DCSDEVICE" ]; then
1487         DCSMP="/mnt/grmlcfg"
1488       fi
1489       eoutdent
1490     fi
1491
1492     # if not specified/present then assume default:
1493     if [ -z "$DCSDEVICE" ]; then
1494       DCSDIR="/live/image"
1495     else
1496       eindent
1497       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1498       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1499       if [ -n "$DCSDIR" ]; then
1500         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1501       else
1502         [ -d $DCSMP ] || mkdir $DCSMP
1503         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1504         mount -o ro -t auto $DCSDEVICE  $DCSMP ; RC="$?"
1505         if [[ $RC == 0 ]]; then
1506           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1507         else
1508           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1509         fi
1510         DCSDIR="$DCSMP"
1511       fi
1512       eoutdent
1513     fi
1514   fi
1515 fi
1516
1517 if [ -n "$DCSDIR" -a "$DCSDIR" != "/live/image" ] ; then
1518   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1519 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1520   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1521 fi
1522 }
1523
1524
1525 config_partconf() {
1526 if checkbootparam 'partconf' ; then
1527  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1528  if [ -n "$MOUNTDEVICE" ]; then
1529    [ -d /mnt/grml ] || mkdir /mnt/grml
1530    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1531     if [[ $RC == 0 ]]; then
1532       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1533       einfo "Copying files from $MOUNTDEVICE over grml system."
1534       for file in `cat /etc/grml/partconf` ; do
1535         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1536         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1537       done && eend 0
1538     else
1539       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1540     fi # mount $MOUNTDEVICE
1541    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1542  else
1543    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1544  fi # [ -n "$MOUNTDEVICE" ]
1545 fi
1546 }
1547 # }}}
1548
1549 # {{{ /cdrom/.*-options
1550 config_debs(){
1551 if checkbootparam 'debs' ; then
1552    iszsh && setopt localoptions shwordsplit
1553    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1554    if [ -z "$DEBS" ] ; then
1555       DEBS="*.deb"
1556    fi
1557    if ! echo $DEBS | grep -q '/'; then
1558      # backwards compatibility: if no path is given get debs from debs/
1559      DEBS="debs/$DEBS"
1560    fi
1561    einfo "Tring to install debian package(s) ${DEBS}"
1562    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1563    dpkg -i $DEBS ; eend $?
1564 fi
1565 }
1566
1567 config_scripts(){
1568 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1569    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1570    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1571      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1572    fi
1573    if ! echo $SCRIPTS | grep -q '/'; then
1574      # backwards compatibility: if no path is given get scripts from scripts/
1575      SCRIPTS="scripts/$SCRIPTS"
1576    fi
1577    if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1578      # we are executing from a GRMLCFG labeled fs
1579      # kick everything we have done before and start over
1580      SCRIPTS="$(cd ${DCSDIR}; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1581    fi
1582    if [ -n "$SCRIPTS" ]; then
1583      SCRIPTS="${DCSDIR}/$SCRIPTS"
1584      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1585        einfo "Trying to execute ${SCRIPTS}"
1586        sh -c $SCRIPTS
1587      elif [ -d "$SCRIPTS" ]; then
1588        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1589        run-parts $SCRIPTS
1590      else
1591        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1592        sh -c $SCRIPTS
1593      fi
1594    fi
1595 fi
1596 }
1597
1598 config_config(){
1599 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1600   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1601   if [ -z "$CONFIG" ]; then
1602     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1603   fi
1604   if [ -n "$CONFIG" ]; then
1605     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1606       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1607
1608       cp -a ${DCSDIR}/${CONFIG}/* /
1609     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1610       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1611
1612       cd /
1613       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1614     else
1615       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1616     fi
1617   fi
1618 fi
1619 }
1620 # }}}
1621
1622 # {{{ confing_umount_dcsdir
1623 config_umount_dcsdir(){
1624    # umount $DCSMP if it was mounted by finddcsdir
1625    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1626 }
1627 # }}}
1628
1629 # {{{ mypath
1630 config_mypath(){
1631 if checkbootparam 'mypath' ; then
1632    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1633    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1634    touch /etc/grml/my_path
1635    chmod 644 /etc/grml/my_path
1636    # make sure the directories exist:
1637    eindent
1638    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1639        if ! [ -d "$i" ] ; then
1640           einfo "Creating directory $i"
1641           mkdir -p "$i" ; eend $?
1642        fi
1643    done
1644    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1645    eoutdent
1646 fi
1647 }
1648 # }}}
1649
1650 # {{{ distcc
1651 config_distcc(){
1652 if checkbootparam 'distcc' ; then
1653  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
1654  if [ -n "$OPTIONS" ]; then
1655     NET=""
1656     INTERFACE=""
1657     if [ -n "$OPTIONS" ]; then
1658       NET="${OPTIONS%%,*}"
1659       R="${OPTIONS#*,}"
1660       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1661         OPTIONS="$R"
1662         INTERFACE="${OPTIONS%%,*}"
1663         R="${OPTIONS#*,}"
1664       fi
1665     fi
1666  fi
1667  CONFIG=/etc/default/distcc
1668  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
1669  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
1670
1671  if [ -n "$INTERFACE" ] ; then
1672    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1673
1674    counter=10
1675    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
1676      counter=$(( counter-1 ))
1677      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
1678      sleep 3
1679      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1680    done
1681  fi
1682
1683  if [ -n "$IP" ] ; then
1684    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
1685
1686    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
1687    eindent
1688     id distccd >/dev/null 2>&1 || \
1689     (
1690       einfo "Creating distcc user" ; \
1691       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
1692     )
1693
1694     einfo "Starting distcc for network ${NET}, listening on ${IP}."
1695    /etc/init.d/distcc start >/dev/null ; eend $?
1696    eoutdent
1697  else
1698    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
1699  fi
1700 fi
1701
1702 if checkbootparam 'gcc'; then
1703  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
1704  eindent
1705  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
1706  eoutdent
1707  rm -f /usr/bin/gcc
1708  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
1709 fi
1710
1711 if checkbootparam 'gpp'; then
1712  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
1713  eindent
1714   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
1715   if [ -x /usr/bin/g++-${GPP} ] ; then
1716      rm -f /usr/bin/g++
1717      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
1718   fi
1719   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
1720   if [ -x /usr/bin/cpp-${GPP} ] ; then
1721      rm -f /usr/bin/cpp
1722      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
1723   fi
1724  eoutdent
1725 fi
1726
1727 }
1728 # }}}
1729
1730 # {{{ load modules
1731 # Notice: use it only on live-cd system, if running from harddisk please
1732 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
1733 # in /etc/runlevel.conf
1734 config_modules(){
1735 MODULES_FILE=/etc/grml/modules
1736 if checkbootparam 'nomodules' ; then
1737   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
1738 elif [ -z "$INSTALLED" ]; then
1739  if [ -r $MODULES_FILE ] ; then
1740   einfo "Loading modules specified in ${MODULES_FILE}:"
1741   eindent
1742   grep '^[^#]' $MODULES_FILE | \
1743   while read module args; do
1744     [ "$module" ] || continue
1745       einfo "${module}"
1746       modprobe $module $args ; eend $?
1747   done
1748   eoutdent
1749  else
1750   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
1751  fi
1752 fi
1753 }
1754 # }}}
1755
1756 # {{{ SW-RAID
1757 config_swraid(){
1758   [ -n "$INSTALLED" ] && return 0
1759
1760   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
1761   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1762      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
1763      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1764   else
1765     [ -e /proc/mdstat ] || modprobe md_mod
1766     if ! [ -x /sbin/mdadm ] ; then
1767        eerror "mdadm not available, can not execute it." ; eend 1
1768     else
1769
1770        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1771        # find out whether we have a valid configuration file already
1772        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1773           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1774           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1775           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1776         else
1777           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1778        fi
1779
1780        if ! checkbootparam 'swraid' ; then
1781           eindent
1782           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1783           eoutdent
1784        else
1785           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1786           eindent
1787            IFSOLD=${IFS:-}
1788            IFS='
1789 '
1790            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
1791                case $line in
1792                  *'No arrays found'*)
1793                    ewarn "$line" ; eend 0
1794                    ;;
1795                  *)
1796                    einfo "$line" ; eend 0
1797                    ;;
1798                esac
1799            done
1800            IFS=$IFSOLD
1801          eoutdent
1802
1803          if [ -r /proc/mdstat ] ; then
1804             eindent
1805             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1806             if [ -z "$MDSTAT" ] ; then
1807                ewarn "No active arrays found" ; eend 0
1808             else
1809                IFSOLD=${IFS:-}
1810                IFS='
1811 '
1812                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1813                    einfo "active arrays: $line" ; eend 0
1814                done
1815                IFS=$IFSOLD
1816             fi
1817             eoutdent
1818          fi # /proc/mdstat
1819        fi # bootoption swraid
1820
1821      fi # is /sbin/mdadm executable?
1822   fi # check for bootoptions
1823 }
1824 # }}}
1825
1826 # {{{ dmraid
1827 config_dmraid(){
1828   [ -n "$INSTALLED" ] && return 0
1829
1830   if checkbootparam 'nodmraid' ; then
1831     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1832     return 0
1833   fi
1834
1835   if ! [ -x /sbin/dmraid ] ; then
1836     eerror "dmraid not available, can not execute it." ; eend 1
1837     return
1838   fi
1839
1840   dmraid_wrapper() {
1841     # usage: dmraid_wrapper <dmraid_option>
1842     [ -n "$1" ] || return 1
1843
1844     IFSOLD=${IFS:-}
1845     IFS='
1846 '
1847     eindent
1848
1849     for line in $(dmraid $1 ; echo errcode:$?); do
1850       case $line in
1851         *'no block devices found'*)
1852           einfo "No block devices found" ; eend 0
1853           break
1854           ;;
1855         *'no raid disks'*)
1856           einfo "No active dmraid devices found" ; eend 0
1857           break
1858           ;;
1859         errcode:0)
1860           eend 0;
1861           ;;
1862         errcode:1)
1863           eend 1
1864           ;;
1865         *)
1866           einfo "$line"
1867           ;;
1868       esac
1869     done
1870
1871     eoutdent
1872     IFS=$IFSOLD
1873   }
1874
1875   if checkbootparam 'dmraid' ; then
1876     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1877     if [ "$ACTION" = "off" ] ; then
1878       # Deactivates all active software RAID sets:
1879       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1880       dmraid_wrapper -an
1881     else
1882       # Activate all software RAID sets discovered:
1883       einfo "Activating present dmraid sets (as requested via dmraid):"
1884       dmraid_wrapper -ay
1885     fi
1886
1887     return
1888   fi
1889
1890   # by default (no special bootoptions) discover all software RAID devices:
1891   einfo "Searching for any present dmraid sets:"
1892   dmraid_wrapper -r
1893 }
1894 # }}}
1895
1896 # {{{ LVM (Logical Volumes)
1897 config_lvm(){
1898   [ -n "$INSTALLED" ] && return 0
1899
1900   if checkbootparam 'nolvm' ; then
1901      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1902   else
1903     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
1904     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
1905        eerror "LVM not available, can not execute it." ; eend 1
1906     else
1907        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1908           einfo "You seem to have logical volumes (LVM) on your system."
1909           eindent
1910           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1911           eend 0
1912           if checkbootparam 'lvm' ; then
1913              einfo "Bootoption LVM found. Searching for logical volumes:"
1914              /etc/init.d/lvm2 start ; eend $?
1915           fi
1916           eoutdent
1917        fi
1918     fi # check for lvm binary
1919   fi # check for bootoption nolvm
1920 }
1921 # }}}
1922
1923 # {{{ debnet: setup network based on an existing one found on a partition
1924 config_debnet(){
1925 if checkbootparam 'debnet' ; then
1926  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1927  /usr/sbin/debnet
1928 fi
1929 }
1930 # }}}
1931
1932 # {{{ disable console blanking
1933 config_blanking(){
1934 if checkbootparam 'noblank' ; then
1935   einfo "Bootoption noblank found. Disabling monitor blanking."
1936   setterm -blank 0 ; eend $?
1937 fi
1938 }
1939 # }}}
1940
1941 # {{{ tohd= bootoption
1942 config_tohd()
1943 {
1944   if checkbootparam 'tohd' ; then
1945      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
1946      if [ -z "$TARGET" ] ; then
1947         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
1948         eerror "Please use something like tohd=/dev/sda9." ; eend 1
1949         return 1
1950      fi
1951
1952      if ! [ -b "$TARGET" ] ; then
1953         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
1954         return 1
1955      fi
1956
1957      if grep -q $TARGET /proc/mounts ; then
1958         eerror "$TARGET already mounted, skipping execution of tohd therefore."
1959         eend 1
1960         return 1
1961      fi
1962
1963      local MOUNTDIR=$(mktemp -d)
1964
1965      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
1966         einfo "Copyring live system to $TARGET - this might take a while"
1967         rsync -a --progress /live/image/live $MOUNTDIR
1968         sync
1969         umount "$MOUNTDIR"
1970         eend $?
1971         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
1972      else
1973         eerror "Error when trying to mount $TARGET, sorry."; eend 1
1974         return 1
1975      fi
1976
1977      rmdir "$MOUNTDIR"
1978   fi
1979 }
1980 # }}}
1981
1982 # {{{ debootstrap: automatic installation
1983 config_debootstrap(){
1984
1985 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
1986
1987 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
1988
1989 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
1990    eindent
1991    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
1992    eoutdent
1993    exit 1
1994 fi
1995
1996 if checkbootparam 'target' ; then
1997   TARGET=''
1998   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
1999   # notice: the following checks whether the given partition is available, if not the skip
2000   # execution of grml-debootstrap as it might result in data loss...
2001   if ! [ -r "$TARGET" ] ; then
2002      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
2003   fi
2004 else
2005   eindent
2006   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
2007   eoutdent
2008   exit 1
2009 fi
2010
2011 if checkbootparam 'grub' ; then
2012   GRUB=''
2013   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2014 fi
2015
2016 if checkbootparam 'groot' ; then
2017   GROOT=''
2018   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2019 fi
2020
2021 if checkbootparam 'release' ; then
2022   RELEASE=''
2023   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2024 fi
2025
2026 if checkbootparam 'mirror' ; then
2027   MIRROR=''
2028   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2029 fi
2030
2031 if checkbootparam 'boot_append' ; then
2032   BOOT_APPEND=''
2033   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2034 fi
2035
2036 if checkbootparam 'password' ; then
2037   PASSWORD=''
2038   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2039 fi
2040
2041 # now check which options are available
2042 if [ -n "TARGET" ] ; then
2043    TARGETCMD="--target $TARGET"
2044 else
2045    TARGETCMD=''
2046    eindent
2047    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2048    eoutdent
2049    exit 1
2050 fi
2051 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2052 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2053 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2054 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2055 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2056 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2057
2058 # and finally write script and execute it
2059 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2060 #!/bin/sh
2061 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2062 EOF
2063
2064 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2065
2066 screen /usr/bin/grml-debootstrap_noninteractive
2067 einfo "Invoking a shell, just exit to continue booting..."
2068 /bin/zsh
2069
2070 fi # checkbootparam "BOOT_IMAGE=debian2hd
2071 }
2072 # }}}
2073
2074 config_virtualbox_shared_folders() {
2075 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
2076   einfo "VirtualBox detected, trying to set up Shared Folders."
2077   if ! modprobe -l | grep -q vboxsf.ko ; then
2078     ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
2079     eend 0
2080   elif ! [ -x /usr/sbin/VBoxService ] ; then
2081     ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
2082     eend 0
2083   else
2084     eindent
2085
2086       einfo "Loading vboxsf driver."
2087       lsmod | grep -q vboxsf || modprobe vboxsf
2088       eend $?
2089
2090       einfo "Adjusting /dev/vboxguest."
2091       chown root:vboxsf /dev/vboxguest
2092       chmod 660 /dev/vboxguest
2093       eend $?
2094
2095       if [ -n "$CONFIG_FSTAB_USER" ] ; then
2096         fstabuser="$CONFIG_FSTAB_USER"
2097       else
2098         fstabuser=$(getent passwd 1000 | cut -d: -f1)
2099       fi
2100       einfo "Adding $fstabuser to group vboxsf."
2101       adduser grml vboxsf &>/dev/null
2102       eend $?
2103
2104       einfo "Starting VBoxService."
2105       VBoxService >/dev/null &
2106       eend $?
2107
2108     eoutdent
2109   fi
2110 fi
2111 }
2112
2113 # {{{ Support customization
2114 config_distri(){
2115 if checkbootparam 'distri'; then
2116   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2117   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2118      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2119      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2120      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2121      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2122   fi
2123 fi
2124 }
2125 # }}}
2126
2127 ## END OF FILE #################################################################
2128 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3