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