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