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