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