Remove forceagp support
[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:/usr/X11R6/bin"
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 's#^1:.*#1:12345:respawn:/usr/bin/openvt -f -c 1 -w -- /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_apm(){
696 if [ -d /proc/acpi ]; then
697   if checkbootparam 'noacpi'; then
698     ewarn "ACPI: Not loading modules as requested by boot option \"noacpi\"." ; eend 0
699   elif checkbootparam 'nogrmlacpi' ; then
700     ewarn "ACPI: Not loading modules as requested by boot option \"nogrmlacpi\"." ; eend 0
701   else
702     einfo "ACPI: Loading modules (disable with boot option noacpi / nogrmlacpi): "
703     eindent
704     found=""
705     for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
706       basename="${a##*/}"
707       basename="${basename%%.*}"
708       case "$basename" in *_acpi)
709        egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
710       esac
711       modprobe $basename >>$DEBUG 2>&1 && found="yes"
712       local BASE="$BASE $basename"
713     done
714     if [ -n "$found" ] ; then
715       einfo "$BASE"  ; eend 0
716     else
717       ewarn "(none)" ; eend 1
718     fi
719     if ! ps x 2>>$DEBUG | grep -q /usr/sbin/acpid ; then
720       einfo "Starting acpi daemon."
721       /etc/init.d/acpid start >>$DEBUG 2>&1 ; eend $?
722     else
723       ewarn "acpi daemon already running."
724       eend 0
725     fi
726     eoutdent
727   fi
728 else
729 # APM
730   if checkbootparam 'noapm'; then
731     ewarn "Skipping APM Bios detection as requested on boot commandline." ; eend 0
732   else
733     modprobe apm power_off=1 >>$DEBUG 2>&1
734     if [ "$?" = "0" ] ; then
735        if [ -x /etc/init.d/apmd ] ;then
736           einfo "APM Bios found, enabling power management functions."
737           /etc/init.d/apmd start ; eend $?
738        fi
739     else
740       eerror "Loading apm module failed." ; eend 1
741     fi
742   fi
743 fi
744 }
745 # }}}
746
747 # {{{ Collect partitions from /proc/partitions first for enabling DMA
748 check_partitions(){
749 partitions=""
750 IDEDISKS=""
751 while read major minor blocks partition relax; do
752   partition="${partition##*/}"
753   [ -z "$partition" -o ! -e "/dev/$partition" ] && continue
754   case "$partition" in
755     hd?) IDEDISKS="$IDEDISKS $partition";;                # IDE  Harddisk, entire disk
756     sd?) ;;                                               # SCSI Harddisk, entire disk
757 #    [hs]d*) partitions="$partitions /dev/$partition";;    # IDE or SCSI disk partition
758     [hs]d*|ub*) partitions="$partitions /dev/$partition";;    # IDE, USB or SCSI disk partition
759   esac
760 done <<EOT
761 $(awk 'BEGIN{old="__start"}{if($0==old){exit}else{old=$0;if($4&&$4!="name"){print $0}}}' /proc/partitions)
762 EOT
763 }
764 check_partitions >/dev/null 2>&1 # avoid output "check_partitions:3: read-only file system"
765 # }}}
766
767 # {{{ Enable DMA for all IDE drives now if not disabled
768 # Notice: Already done by linuxrc, but make sure it's done also on harddisk-installed systems
769 config_dma(){
770 if checkbootparam 'nodma'; then
771   ewarn "Skipping DMA accelleration as requested on boot commandline." ; eend 0
772 else
773   for d in $(cd /proc/ide 2>>$DEBUG && echo hd[a-z]); do
774     if test -d /proc/ide/$d; then
775       if egrep -q 'using_dma[ \t]+0' /proc/ide/$d/settings 2>>$DEBUG; then
776         MODEL="$(cat /proc/ide/$d/model 2>>$DEBUG)"
777         test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]"
778         einfo "Enabling DMA acceleration for: ${WHITE}$d        ${YELLOW}[${MODEL}]${NORMAL}"
779         echo "using_dma:1" >/proc/ide/$d/settings
780         eend 0
781       fi
782     fi
783   done
784 fi
785 }
786 # }}}
787
788 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
789 config_fstab(){
790
791 NOSWAP="yes" # we do not use swap by default!
792 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
793    NOSWAP=''
794    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
795 fi
796
797 # Scan for swap, config, homedir - but only in live-mode
798 if [ -z "$INSTALLED" ] ; then
799    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
800    GRML_IMG=""
801    GRML_SWP=""
802    HOMEDIR="$(getbootparam 'home')"
803    if [ -n "$partitions" ]; then
804       while read p m f relax; do
805         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
806         partoptions="users,exec"
807         fnew=""
808         # it's a swap partition?
809         case "$f" in swap)
810           eindent
811           if [ -n "$NOSWAP" ]; then
812              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
813              eend 0
814           else
815              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
816                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
817                      if [ -n "$ANYSWAP" ] ; then
818                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
819                         swapon $p 2>>$DEBUG ; eend $?
820                      else
821                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
822                      fi
823                      ;;
824                    *)
825                      if [[ "$p" == LABEL* ]] ; then
826                         p=$(blkid -t $p | awk -F: '{print $1}')
827                      fi
828                      if grep -q $p /proc/swaps ; then
829                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
830                      else
831                         if [ -b "$p" ] ; then
832                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
833                         swapon $p 2>>$DEBUG ; eend $?
834                         else
835                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
836                         fi
837                      fi
838                      ;;
839              esac # dd-check
840           fi # -n "$NOSWAP
841           eoutdent
842           continue
843           ;;
844         esac # it's a swap partition?
845
846         # mount read-only
847         MOUNTOPTS="ro"
848         case "$f" in
849           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
850           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
851           *) continue ;;
852           # *) NONEFOUND='1'; continue ;;
853         esac
854
855         # use a swapfile
856         if [ -z "$NOSWAP" ] ; then
857            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
858            # Activate swapfile, if exists
859            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
860         fi
861         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
862            mount -o remount,rw $m && MOUNTED=1
863            if swapon "$SWAPFILE" 2>>$DEBUG ; then
864               eindent
865                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
866               eoutdent
867               fnew="$SWAPFILE swap swap defaults 0 0"
868               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
869               GRML_SWP="$GRML_SWP $SWAPFILE"
870               eend 0
871            fi
872            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
873         fi
874
875         # use a image as home
876         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
877         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
878            if [ -n "$HOMEDIR" ]; then
879               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
880                  continue
881               fi
882            fi
883            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
884               GRML_IMG="$IMAGE"
885               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
886            fi
887         fi
888         eend 0
889
890         # Umount, if not in use
891         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
892
893       done <<EOT
894       $(cat /etc/fstab)
895 EOT
896    fi # -n $partitions
897 fi # -z $INSTALLED
898 }
899 # }}}
900
901 # {{{ Mouse
902 config_mouse(){
903 if [ -n "$MOUSE_DEVICE" ] ; then
904   einfo "Detecting mouse: ${MOUSE_FULLNAME} at ${MOUSE_DEVICE}" ; eend $?
905 fi
906 }
907 # }}}
908
909 # {{{ IPv6 configuration
910 # Load IPv6 kernel module and print IP adresses
911 config_ipv6(){
912 if checkbootparam 'ipv6'; then
913   einfo "Enabling IPv6 as requested on boot commandline (sleeping for 2 seconds)"
914   modprobe ipv6
915   # we probably need some time until stateless autoconfiguration has happened
916   sleep 2
917   NETDEVICES="$(awk -F: '/eth.:|tr.:|wlan.:/{print $1}' /proc/net/dev 2>>$DEBUG)"
918   for DEVICE in `echo "$NETDEVICES"`; do
919     eindent
920       einfo "$DEVICE:"
921       ADDRESSES="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{print $3}')"
922       COUNT="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{ sum += 1};END {print sum }')"
923       eindent
924         for ADDR in `echo "$ADDRESSES"` ; do
925             einfo "$ADDR"
926         done
927         if [ "$COUNT" -eq "0" ] ; then
928            einfo "(none)" ; eend 1
929         fi
930       eoutdent
931     eoutdent
932   done
933   eend 0
934 fi
935 }
936 # }}}
937
938 # {{{ CPU-detection
939 config_cpu(){
940 if checkbootparam 'nocpu'; then
941   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
942   return 0
943 fi
944
945 if [[ $(grep -c processor /proc/cpuinfo) -gt 1 ]] ; then
946    einfo "Detecting CPU:"
947    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)
948    echo $CPU | sed 's/ \{1,\}/ /g'
949    eend 0
950 else
951    einfo "Detecting 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
952 fi
953
954 # no cpufreq setup inside VirtualBox
955 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
956    einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0
957    return 0
958 fi
959
960 if [ -x /etc/init.d/loadcpufreq ] ; then
961    einfo "Trying to set up cpu frequency scaling:"
962    eindent
963    SKIP_CPU_GOVERNOR=''
964    LOADCPUFREQ=$(mktemp)
965    /etc/init.d/loadcpufreq start >"$LOADCPUFREQ" 2>&1 ; RC=$?
966    if grep -q FATAL "$LOADCPUFREQ" ; then
967       eindent
968         SKIP_CPU_GOVERNOR=1
969         oldIFS="$IFS"
970         IFS="
971 "
972          for line in $(grep FATAL "$LOADCPUFREQ" | sed 's/.*FATAL: //; s/ (.*)//') ; do
973              eerror "$line" ; eend $RC
974          done
975          IFS="$oldIFS"
976       eoutdent
977    elif grep -q done "$LOADCPUFREQ" ; then
978       MODULE=$(grep done "$LOADCPUFREQ" | sed 's/.*done (\(.*\))./\1/')
979       if [ -n "$MODULE" -a "$MODULE" != none ]; then
980          einfo "Loading cpufreq kernel module $MODULE" ; eend 0
981       else
982          ewarn "Could not find an appropriate kernel module for cpu frequency scaling." ; eend 1
983       fi
984    fi
985
986    rm -f $LOADCPUFREQ
987
988    if [ -z "$SKIP_CPU_GOVERNOR" ] ; then
989       einfo "Loading cpufreq_ondemand, setting ondemand governor"
990       RC=0
991       if modprobe cpufreq_ondemand ; RC=$? ; then
992          for file in $(find /sys/devices/system/cpu/ -name scaling_governor 2>/dev/null) ; do
993             echo ondemand > $file
994          done
995       fi
996       eend $RC
997    fi # cpu-governor
998
999    eoutdent
1000 fi
1001 }
1002 # }}}
1003
1004 # {{{ autostart of ssh
1005 config_ssh(){
1006 if checkbootparam 'ssh' ; then
1007    SSH_PASSWD=''
1008    SSH_PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
1009    einfo "Bootoption ssh found, trying to set password for user grml."
1010    eindent
1011    if [ -z "$SSH_PASSWD" ] ; then
1012       if [ -x /usr/bin/apg ] ; then
1013          SSH_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1014       elif [ -x /usr/bin/gpw ] ; then
1015          SSH_PASSWD="$(gpw 1)"
1016       elif [ -x /usr/bin/pwgen ] ; then
1017          SSH_PASSWD="$(pwgen -1 8)"
1018       elif [ -x /usr/bin/hexdump ] ; then
1019          SSH_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1020       elif [ -n "$RANDOM" ] ; then
1021          SSH_PASSWD="grml${RANDOM}"
1022       else
1023          SSH_PASSWD=''
1024          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1025          eend 1
1026       fi
1027
1028       if [ -n "$SSH_PASSWD" ] ; then
1029          ewarn "No given password for ssh found. Using random password: $SSH_PASSWD" ; eend 0
1030       fi
1031    fi
1032    eoutdent
1033
1034    # finally check if we have a password we can use:
1035    if [ -n "$SSH_PASSWD" ] ; then
1036       # chpasswd sucks, seriously.
1037       if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1038         echo "grml:$SSH_PASSWD" | chpasswd -m
1039       else
1040         echo "grml:$SSH_PASSWD" | chpasswd
1041       fi
1042    fi
1043
1044    einfo 'Starting secure shell server in background.'
1045    /etc/init.d/rmnologin start >>$DEBUG 2>>$DEBUG
1046    /etc/init.d/ssh start >>$DEBUG 2>>$DEBUG &
1047    eend $?
1048
1049    eindent
1050    ewarn 'Warning: please change the password for user grml as soon as possible!'
1051    eoutdent
1052 fi
1053 }
1054 # }}}
1055
1056 # {{{ autostart of x11vnc
1057 config_vnc(){
1058
1059 USER=grml # TODO: make it dynamically configurable
1060 if checkbootparam 'vnc' ; then
1061    VNC_PASSWD=''
1062    VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)"
1063    einfo "Bootoption vnc found, trying to set password for user $USER."
1064    eindent
1065    if [ -z "$VNC_PASSWD" ] ; then
1066       if [ -x /usr/bin/apg ] ; then
1067          VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1068       elif [ -x /usr/bin/gpw ] ; then
1069          VNC_PASSWD="$(gpw 1)"
1070       elif [ -x /usr/bin/pwgen ] ; then
1071          VNC_PASSWD="$(pwgen -1 8)"
1072       elif [ -x /usr/bin/hexdump ] ; then
1073          VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1074       elif [ -n "$RANDOM" ] ; then
1075          VNC_PASSWD="${USER}${RANDOM}"
1076       else
1077          VNC_PASSWD=''
1078          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1079          eend 1
1080       fi
1081
1082       if [ -n "$VNC_PASSWD" ] ; then
1083          ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0
1084       fi
1085    fi
1086    eoutdent
1087
1088    # finally check if we have a password we can use:
1089    if [ -n "$VNC_PASSWD" ] ; then
1090
1091       VNCDIR="/home/${USER}/.vnc"
1092       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1093
1094       if [ ! -x /usr/bin/x11vnc ] ; then
1095          eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package."
1096          eend 1
1097       else
1098          /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $?
1099          /bin/chown -R "$USER": "$VNCDIR"
1100       fi
1101    fi
1102    if checkbootparam 'vnc_connect' ; then
1103       VNC_CONNECT=''
1104       VNC_CONNECT="$(getbootparam 'vnc_connect' 2>>$DEBUG)"
1105       einfo "Bootoption vnc_connect found, will start vnc with connect to $VNC_CONNECT."
1106       #store the options in a file
1107       VNCDIR="/home/${USER}/.vnc"
1108       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1109       echo " --connect $VNC_CONNECT " >> $VNCDIR/options
1110    fi
1111 fi
1112 }
1113 # }}}
1114
1115 # {{{ set password for user grml
1116 config_passwd(){
1117 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1118   einfo "Bootoption passwd found."
1119   PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1120   if [ -n "$PASSWD" ] ; then
1121     echo "grml:$PASSWD" | chpasswd -m ; eend $?
1122   else
1123     eerror "No given password for ssh found. Autostart of SSH will not work." ; eend 1
1124   fi
1125   eindent
1126     ewarn "Warning: please change the password for user grml set via bootparameter as soon as possible!"
1127   eoutdent
1128 fi
1129 }
1130 # }}}
1131
1132 # {{{ Sound
1133 config_mixer () {
1134    if ! [ -x /usr/bin/amixer ] ; then
1135       eerror "amixer binary not available. Can not set sound volumes therefore."
1136       eend 1
1137    else
1138       if ! [ -r /proc/asound/cards ] ; then
1139          ewarn "No soundcard present, skipping mixer settings therefore."
1140          eend 0
1141          return
1142       fi
1143
1144       for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do
1145          einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\""
1146          eindent
1147
1148          if checkbootparam 'vol' ; then
1149             VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1150             if [ -z "$VOL" ] ; then
1151                eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)."
1152                VOL='75'
1153                eend 1
1154             fi
1155          else
1156             VOL='75'
1157          fi
1158
1159          if checkbootparam 'nosound' ; then
1160             einfo "Muting sound devices on request."
1161             ERROR=$(amixer -q set Master mute)
1162             RC=$?
1163             if [ -n "$ERROR" ] ; then
1164                eindent
1165                eerror "Problem muting sound devices: $ERROR"
1166                eoutdent
1167             fi
1168             eend $RC
1169          elif [ -z "$INSTALLED" ] ; then
1170             einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1171
1172             if checkbootparam 'micvol' ; then
1173                MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1174             else
1175                MICVOL=0
1176             fi
1177
1178             for CONTROL in Master PCM ; do
1179                if amixer -q | grep -q "Simple mixer control '$CONTROL'" ; then
1180                   amixer -q set "${CONTROL}" "${VOL}"%
1181                   eend $?
1182                fi
1183             done
1184
1185             if [ ${MICVOL} -ne 0 ] ; then
1186                einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1187                amixer -q set "Mic" $MICVOL &> /dev/null
1188                eend $?
1189             fi
1190          fi # checkbootparam 'nosound'
1191          eoutdent
1192       done
1193    fi
1194 }
1195 # }}}
1196
1197 # {{{ modem detection
1198 config_modem(){
1199 if checkbootparam 'nomodem'; then
1200   ewarn "Skipping check for AC97 modem controller as requested on boot commandline." ; eend 0
1201 else
1202   if [ -x /etc/init.d/sl-modem-daemon ] ; then
1203      if lspci | grep Intel | grep -q "AC'97 Modem Controller" ; then
1204         einfo "AC97 modem controller detected. Start it running 'Start sl-modem-daemon'."
1205         eend 0
1206      fi
1207   fi
1208 fi
1209 }
1210 # }}}
1211
1212 # {{{ wondershaper
1213 config_wondershaper(){
1214  if checkbootparam 'wondershaper' ; then
1215     WONDER="$(getbootparam 'wondershaper' 2>>$DEBUG)"
1216     CMD=wondershaper
1217     DEVICE=""
1218     DOWNSTREAM=""
1219     UPSTREAM=""
1220     if [ -n "$WONDER" ]; then
1221       # Extra options
1222       DEVICE="${WONDER%%,*}"
1223       R="${WONDER#*,}"
1224       if [ -n "$R" -a "$R" != "$WONDER" ]; then
1225         WONDER="$R"
1226         DOWNSTREAM="${WONDER%%,*}"
1227         R="${WONDER#*,}"
1228         if [ -n "$R" -a "$R" != "$WONDER" ]; then
1229           WONDER="$R"
1230           UPSTREAM="${WONDER%%,*}"
1231           R="${WONDER#*,}"
1232         fi
1233       fi
1234     fi
1235     [ -n "$DEVICE" ]     && CMD="$CMD $DEVICE"
1236     [ -n "$DOWNSTREAM" ] && CMD="$CMD $DOWNSTREAM"
1237     [ -n "$UPSTREAM" ]   && CMD="$CMD $UPSTREAM"
1238     einfo "Starting wondershaper (${CMD}) in background."
1239     ( sh -c $CMD & ) && eend 0
1240  fi
1241 }
1242 # }}}
1243
1244 # {{{ syslog-ng
1245 config_syslog(){
1246  if checkbootparam 'nosyslog'; then
1247     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1248  else
1249     SYSLOGD=''
1250     [ -x /etc/init.d/syslog-ng ] && SYSLOGD='syslog-ng'
1251     [ -x /etc/init.d/rsyslog   ] && SYSLOGD='rsyslog'
1252     [ -x /etc/init.d/dsyslog   ] && SYSLOGD='dsyslog'
1253     [ -x /etc/init.d/sysklogd  ] && SYSLOGD='sysklogd'
1254     [ -x /etc/init.d/inetutils-syslogd ] && SYSLOGD='inetutils-syslogd'
1255
1256     if [ -z "$SYSLOGD" ] ; then
1257        eerror "No syslog daemon found." ; eend 1
1258     else
1259        einfo "Starting $SYSLOGD in background."
1260        /etc/init.d/$SYSLOGD start >>$DEBUG &
1261        eend 0
1262     fi
1263  fi
1264 }
1265 # }}}
1266
1267 # {{{ gpm
1268 config_gpm(){
1269  if checkbootparam 'nogpm'; then
1270   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1271  else
1272    if ! [ -r /dev/input/mice ] ; then
1273       eerror "No mouse found - not starting GPM." ; eend 1
1274    else
1275       einfo "Starting gpm in background."
1276       /etc/init.d/gpm start >>$DEBUG &
1277       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start >>$DEBUG ) &
1278       eend 0
1279    fi
1280  fi
1281 }
1282 # }}}
1283
1284 # {{{ services
1285 config_services(){
1286  if checkbootparam 'services' ; then
1287     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1288     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1289     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1290     for service in $(echo -e $SERVICELIST) ; do
1291       # support running (custom) init scripts in non-blocking mode
1292       # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1293       if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1294         einfo "Starting service ${service}."
1295         /etc/init.d/${service} start >>$DEBUG
1296       else
1297         einfo "Starting service ${service} in background."
1298         /etc/init.d/${service} start >>$DEBUG &
1299       fi
1300     done
1301     eend $?
1302  fi
1303 }
1304 # }}}
1305
1306 # {{{ remote files
1307 get_remote_file() {
1308   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1309   SOURCE=$(eval echo "$1")
1310   TARGET="$2"
1311   getconfig() {
1312   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1313        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1314   }
1315   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1316   counter=10
1317   while ! getconfig && [[ "$counter" != 0 ]] ; do
1318     echo -n "Sleeping for 1 second and trying to get config again... "
1319     counter=$(( counter-1 ))
1320     echo "$counter tries left" ; sleep 1
1321   done
1322   if [ -s "$TARGET" ] ; then
1323     einfo "Downloading was successfull." ; eend 0
1324     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1325     md5sum ${TARGET} ; eend 0
1326     return 0;
1327   else
1328     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1329     return 1;
1330  fi
1331 }
1332 # }}}
1333
1334 # {{{ config files
1335 config_netconfig(){
1336  if checkbootparam 'netconfig' ; then
1337   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1338   CONFIGFILE='/tmp/netconfig.grml'
1339
1340   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1341     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1342   fi
1343
1344  fi
1345 }
1346 # }}}
1347
1348 # {{{ remote scripts
1349 config_netscript() {
1350  if checkbootparam 'netscript' ; then
1351   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1352   SCRIPTFILE='/tmp/netscript.grml'
1353
1354   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1355     chmod +x ${SCRIPTFILE}
1356     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1357   fi
1358
1359  fi
1360 }
1361 # }}}
1362
1363 # {{{ fix/workaround for unionfs
1364 fix_unionfs(){
1365   if [ -z "$INSTALLED" ]; then
1366    touch /var/cache/apt/*cache.bin
1367   fi
1368 }
1369 # }}}
1370
1371 # {{{ start X window system via grml-x
1372 config_x_startup(){
1373 # make sure we start X only if startx is used *before* a nostartx option
1374 # so it's possible to disable automatic X startup using nostart
1375 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1376  if [ -x "$(which X)" ] ; then
1377   if [ -z "$INSTALLED" ] ; then
1378    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1379    if [ -z "$WINDOWMANAGER" ] ; then
1380      einfo "No window manager specified. Taking ${WHITE}wm-ng${NORMAL} as default." && eend 0
1381      WINDOWMANAGER="wm-ng"
1382    else
1383      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1384    fi
1385    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1386    config_userfstab || fstabuser='grml'
1387  cat>|/etc/init.d/xstartup<<EOF
1388 #!/bin/sh
1389 su $fstabuser -c "/usr/bin/grml-x $WINDOWMANAGER"
1390 EOF
1391    chmod 755 /etc/init.d/xstartup
1392
1393    # adjust inittab for xstartup
1394    if grep -q '^6:' /etc/inittab ; then
1395       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
1396    else # just append tty6 to inittab if no definition is present:
1397       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
1398    fi
1399
1400    /sbin/telinit q ; eend $?
1401
1402    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1403       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1404    else
1405       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1406    fi
1407
1408   else
1409     eerror "We are not running in live mode - startx will not work, skipping it."
1410     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1411   fi
1412  else
1413    eerror "/usr/X11R6/bin/X is not present on this grml flavour."
1414    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1415  fi
1416 fi
1417 }
1418 # }}}
1419
1420 # {{{ configuration framework
1421 config_extract(){
1422 if checkbootparam 'extract' ; then
1423  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1424  EXTRACTOPTIONS="-- -x $EXTRACT"
1425 fi
1426 }
1427
1428 config_finddcsdir() {
1429 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1430 #    on the command line, nothing is changed and the dcs files are
1431 #    searched within the .iso, $dcs-dir is set to the root directory
1432 #    within the .iso
1433 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1434 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1435 #    set, $dcs-dir is set to the root directory within the .iso.
1436 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1437 #    foo, even if a GRMLCFG partition is present.
1438 DCSDIR=""
1439 DCSMP="/mnt/grml"
1440 # autoconfig, see issue673
1441 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1442 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1443 if checkbootparam 'noautoconfig' || checkbootparam 'forensic' ; then
1444   ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1445 else
1446   if [ -z "$INSTALLED" ] ; then
1447     if checkbootparam 'myconfig' ; then
1448       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1449       if [ -z "$DCSDEVICE" ]; then
1450         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1451       fi # [ -z "$DCSDEVICE" ]
1452     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1453       einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1454       eindent
1455       # We do need the following fix so floppy disk is available to blkid in any case :-/
1456       if [ -r /dev/fd0 ] ; then
1457         einfo "Floppy device detected. Trying to access floppy disk."
1458         if timeout 4 dd if=/dev/fd0 of=/dev/null bs=512 count=1 >>$DEBUG 2>&1 ; then
1459            blkid /dev/fd0 >>$DEBUG 2>&1
1460         fi
1461       fi
1462       DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1463       if [ -n "$DCSDEVICE" ]; then
1464         DCSMP="/mnt/grmlcfg"
1465       fi
1466       eoutdent
1467     fi
1468
1469     # if not specified/present then assume default:
1470     if [ -z "$DCSDEVICE" ]; then
1471       DCSDIR="/live/image"
1472     else
1473       eindent
1474       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1475       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1476       if [ -n "$DCSDIR" ]; then
1477         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1478       else
1479         [ -d $DCSMP ] || mkdir $DCSMP
1480         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1481         mount -o ro -t auto $DCSDEVICE  $DCSMP ; RC="$?"
1482         if [[ $RC == 0 ]]; then
1483           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1484         else
1485           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1486         fi
1487         DCSDIR="$DCSMP"
1488       fi
1489       eoutdent
1490     fi
1491   fi
1492 fi
1493
1494 if [ -n "$DCSDIR" -a "$DCSDIR" != "/live/image" ] ; then
1495   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1496 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1497   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1498 fi
1499 }
1500
1501
1502 config_partconf() {
1503 if checkbootparam 'partconf' ; then
1504  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1505  if [ -n "$MOUNTDEVICE" ]; then
1506    [ -d /mnt/grml ] || mkdir /mnt/grml
1507    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1508     if [[ $RC == 0 ]]; then
1509       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1510       einfo "Copying files from $MOUNTDEVICE over grml system."
1511       for file in `cat /etc/grml/partconf` ; do
1512         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1513         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1514       done && eend 0
1515     else
1516       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1517     fi # mount $MOUNTDEVICE
1518    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1519  else
1520    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1521  fi # [ -n "$MOUNTDEVICE" ]
1522 fi
1523 }
1524 # }}}
1525
1526 # {{{ /cdrom/.*-options
1527 config_debs(){
1528 if checkbootparam 'debs' ; then
1529    iszsh && setopt localoptions shwordsplit
1530    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1531    if [ -z "$DEBS" ] ; then
1532       DEBS="*.deb"
1533    fi
1534    if ! echo $DEBS | grep -q '/'; then
1535      # backwards compatibility: if no path is given get debs from debs/
1536      DEBS="debs/$DEBS"
1537    fi
1538    einfo "Tring to install debian package(s) ${DEBS}"
1539    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1540    dpkg -i $DEBS ; eend $?
1541 fi
1542 }
1543
1544 config_scripts(){
1545 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1546    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1547    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1548      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1549    fi
1550    if ! echo $SCRIPTS | grep -q '/'; then
1551      # backwards compatibility: if no path is given get scripts from scripts/
1552      SCRIPTS="scripts/$SCRIPTS"
1553    fi
1554    if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1555      # we are executing from a GRMLCFG labeled fs
1556      # kick everything we have done before and start over
1557      SCRIPTS="$(cd ${DCSDIR}; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1558    fi
1559    if [ -n "$SCRIPTS" ]; then
1560      SCRIPTS="${DCSDIR}/$SCRIPTS"
1561      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1562        einfo "Trying to execute ${SCRIPTS}"
1563        sh -c $SCRIPTS
1564      elif [ -d "$SCRIPTS" ]; then
1565        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1566        run-parts $SCRIPTS
1567      else
1568        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1569        sh -c $SCRIPTS
1570      fi
1571    fi
1572 fi
1573 }
1574
1575 config_config(){
1576 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1577   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1578   if [ -z "$CONFIG" ]; then
1579     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1580   fi
1581   if [ -n "$CONFIG" ]; then
1582     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1583       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1584
1585       cp -a ${DCSDIR}/${CONFIG}/* /
1586     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1587       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1588
1589       cd /
1590       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1591     else
1592       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1593     fi
1594   fi
1595 fi
1596 }
1597 # }}}
1598
1599 # {{{ confing_umount_dcsdir
1600 config_umount_dcsdir(){
1601    # umount $DCSMP if it was mounted by finddcsdir
1602    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1603 }
1604 # }}}
1605
1606 # {{{ mypath
1607 config_mypath(){
1608 if checkbootparam 'mypath' ; then
1609    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1610    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1611    touch /etc/grml/my_path
1612    chmod 644 /etc/grml/my_path
1613    # make sure the directories exist:
1614    eindent
1615    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1616        if ! [ -d "$i" ] ; then
1617           einfo "Creating directory $i"
1618           mkdir -p "$i" ; eend $?
1619        fi
1620    done
1621    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1622    eoutdent
1623 fi
1624 }
1625 # }}}
1626
1627 # {{{ distcc
1628 config_distcc(){
1629 if checkbootparam 'distcc' ; then
1630  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
1631  if [ -n "$OPTIONS" ]; then
1632     NET=""
1633     INTERFACE=""
1634     if [ -n "$OPTIONS" ]; then
1635       NET="${OPTIONS%%,*}"
1636       R="${OPTIONS#*,}"
1637       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1638         OPTIONS="$R"
1639         INTERFACE="${OPTIONS%%,*}"
1640         R="${OPTIONS#*,}"
1641       fi
1642     fi
1643  fi
1644  CONFIG=/etc/default/distcc
1645  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
1646  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
1647
1648  if [ -n "$INTERFACE" ] ; then
1649    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1650
1651    counter=10
1652    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
1653      counter=$(( counter-1 ))
1654      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
1655      sleep 3
1656      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1657    done
1658  fi
1659
1660  if [ -n "$IP" ] ; then
1661    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
1662
1663    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
1664    eindent
1665     id distccd >/dev/null 2>&1 || \
1666     (
1667       einfo "Creating distcc user" ; \
1668       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
1669     )
1670
1671     einfo "Starting distcc for network ${NET}, listening on ${IP}."
1672    /etc/init.d/distcc start >/dev/null ; eend $?
1673    eoutdent
1674  else
1675    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
1676  fi
1677 fi
1678
1679 if checkbootparam 'gcc'; then
1680  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
1681  eindent
1682  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
1683  eoutdent
1684  rm -f /usr/bin/gcc
1685  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
1686 fi
1687
1688 if checkbootparam 'gpp'; then
1689  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
1690  eindent
1691   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
1692   if [ -x /usr/bin/g++-${GPP} ] ; then
1693      rm -f /usr/bin/g++
1694      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
1695   fi
1696   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
1697   if [ -x /usr/bin/cpp-${GPP} ] ; then
1698      rm -f /usr/bin/cpp
1699      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
1700   fi
1701  eoutdent
1702 fi
1703
1704 }
1705 # }}}
1706
1707 # {{{ load modules
1708 # Notice: use it only on live-cd system, if running from harddisk please
1709 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
1710 # in /etc/runlevel.conf
1711 config_modules(){
1712 MODULES_FILE=/etc/grml/modules
1713 if checkbootparam 'nomodules' ; then
1714   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
1715 elif [ -z "$INSTALLED" ]; then
1716  if [ -r $MODULES_FILE ] ; then
1717   einfo "Loading modules specified in ${MODULES_FILE}:"
1718   eindent
1719   grep '^[^#]' $MODULES_FILE | \
1720   while read module args; do
1721     [ "$module" ] || continue
1722       einfo "${module}"
1723       modprobe $module $args ; eend $?
1724   done
1725   eoutdent
1726  else
1727   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
1728  fi
1729 fi
1730 }
1731 # }}}
1732
1733 # {{{ 915resolution
1734 config_915resolution(){
1735 if checkbootparam '915resolution' ; then
1736  OPTIONS="$(getbootparam '915resolution' 2>>$DEBUG)"
1737   if [ -x /usr/sbin/915resolution ]; then
1738     CMD=915resolution
1739     MODE=""
1740     XRESO=""
1741     YRESO=""
1742     if [ -n "$OPTIONS" ]; then
1743       # Extra options
1744       MODE="${OPTIONS%%,*}"
1745       R="${OPTIONS#*,}"
1746       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1747         OPTIONS="$R"
1748         XRESO="${OPTIONS%%,*}"
1749         R="${OPTIONS#*,}"
1750         if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1751           OPTIONS="$R"
1752           YRESO="${OPTIONS%%,*}"
1753           R="${OPTIONS#*,}"
1754         fi
1755       fi
1756     fi
1757     einfo "Running 915resolution with options ${MODE} ${XRESO} ${YRESO}."
1758     [ -n "$MODE" ] && [ -n "$XRESO"  ] && [ -n "$YRESO" ]  && ( sh -c "$CMD $MODE $XRESO $YRESO" & )
1759     eend 0
1760   fi
1761 fi
1762 }
1763 # }}}
1764
1765 # {{{ SW-RAID
1766 config_swraid(){
1767   [ -n "$INSTALLED" ] && return 0
1768
1769   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
1770   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1771      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
1772      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1773   else
1774     if ! [ -x /sbin/mdadm ] ; then
1775        eerror "mdadm not available, can not execute it." ; eend 1
1776     else
1777
1778        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1779        # find out whether we have a valid configuration file already
1780        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1781           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1782           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1783           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1784         else
1785           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1786        fi
1787
1788        if ! checkbootparam 'swraid' ; then
1789           eindent
1790           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1791           eoutdent
1792        else
1793           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1794           eindent
1795            IFSOLD=${IFS:-}
1796            IFS='
1797 '
1798            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
1799                case $line in
1800                  *'No arrays found'*)
1801                    ewarn "$line" ; eend 0
1802                    ;;
1803                  *)
1804                    einfo "$line" ; eend 0
1805                    ;;
1806                esac
1807            done
1808            IFS=$IFSOLD
1809          eoutdent
1810
1811          if [ -r /proc/mdstat ] ; then
1812             eindent
1813             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1814             if [ -z "$MDSTAT" ] ; then
1815                ewarn "No active arrays found" ; eend 0
1816             else
1817                IFSOLD=${IFS:-}
1818                IFS='
1819 '
1820                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1821                    einfo "active arrays: $line" ; eend 0
1822                done
1823                IFS=$IFSOLD
1824             fi
1825             eoutdent
1826          fi # /proc/mdstat
1827        fi # bootoption swraid
1828
1829      fi # is /sbin/mdadm executable?
1830   fi # check for bootoptions
1831 }
1832 # }}}
1833
1834 # {{{ dmraid
1835 config_dmraid(){
1836   [ -n "$INSTALLED" ] && return 0
1837
1838   if checkbootparam 'nodmraid' ; then
1839     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1840     return 0
1841   fi
1842
1843   if ! [ -x /sbin/dmraid ] ; then
1844     eerror "dmraid not available, can not execute it." ; eend 1
1845     return
1846   fi
1847
1848   dmraid_wrapper() {
1849     # usage: dmraid_wrapper <dmraid_option>
1850     [ -n "$1" ] || return 1
1851
1852     IFSOLD=${IFS:-}
1853     IFS='
1854 '
1855     eindent
1856
1857     for line in $(dmraid $1 ; echo errcode:$?); do
1858       case $line in
1859         *'no block devices found'*)
1860           einfo "No block devices found" ; eend 0
1861           break
1862           ;;
1863         *'no raid disks'*)
1864           einfo "No active dmraid devices found" ; eend 0
1865           break
1866           ;;
1867         errcode:0)
1868           eend 0;
1869           ;;
1870         errcode:1)
1871           eend 1
1872           ;;
1873         *)
1874           einfo "$line"
1875           ;;
1876       esac
1877     done
1878
1879     eoutdent
1880     IFS=$IFSOLD
1881   }
1882
1883   if checkbootparam 'dmraid' ; then
1884     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1885     if [ "$ACTION" = "off" ] ; then
1886       # Deactivates all active software RAID sets:
1887       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1888       dmraid_wrapper -an
1889     else
1890       # Activate all software RAID sets discovered:
1891       einfo "Activating present dmraid sets (as requested via dmraid):"
1892       dmraid_wrapper -ay
1893     fi
1894
1895     return
1896   fi
1897
1898   # by default (no special bootoptions) discover all software RAID devices:
1899   einfo "Searching for any present dmraid sets:"
1900   dmraid_wrapper -r
1901 }
1902 # }}}
1903
1904 # {{{ LVM (Logical Volumes)
1905 config_lvm(){
1906   [ -n "$INSTALLED" ] && return 0
1907
1908   if checkbootparam 'nolvm' ; then
1909      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1910   else
1911     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
1912     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
1913        eerror "LVM not available, can not execute it." ; eend 1
1914     else
1915        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1916           einfo "You seem to have logical volumes (LVM) on your system."
1917           eindent
1918           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1919           eend 0
1920           if checkbootparam 'lvm' ; then
1921              einfo "Bootoption LVM found. Searching for logical volumes:"
1922              /etc/init.d/lvm2 start ; eend $?
1923           fi
1924           eoutdent
1925        fi
1926     fi # check for lvm binary
1927   fi # check for bootoption nolvm
1928 }
1929 # }}}
1930
1931 # {{{ debnet: setup network based on an existing one found on a partition
1932 config_debnet(){
1933 if checkbootparam 'debnet' ; then
1934  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1935  /usr/sbin/debnet
1936 fi
1937 }
1938 # }}}
1939
1940 # {{{ disable console blanking
1941 config_blanking(){
1942 if checkbootparam 'noblank' ; then
1943   einfo "Bootoption noblank found. Disabling monitor blanking."
1944   setterm -blank 0 ; eend $?
1945 fi
1946 }
1947 # }}}
1948
1949 # {{{ tohd= bootoption
1950 config_tohd()
1951 {
1952   if checkbootparam 'tohd' ; then
1953      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
1954      if [ -z "$TARGET" ] ; then
1955         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
1956         eerror "Please use something like tohd=/dev/sda9." ; eend 1
1957         return 1
1958      fi
1959
1960      if ! [ -b "$TARGET" ] ; then
1961         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
1962         return 1
1963      fi
1964
1965      if grep -q $TARGET /proc/mounts ; then
1966         eerror "$TARGET already mounted, skipping execution of tohd therefore."
1967         eend 1
1968         return 1
1969      fi
1970
1971      local MOUNTDIR=$(mktemp -d)
1972
1973      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
1974         einfo "Copyring live system to $TARGET - this might take a while"
1975         rsync -a --progress /live/image/live $MOUNTDIR
1976         sync
1977         umount "$MOUNTDIR"
1978         eend $?
1979         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
1980      else
1981         eerror "Error when trying to mount $TARGET, sorry."; eend 1
1982         return 1
1983      fi
1984
1985      rmdir "$MOUNTDIR"
1986   fi
1987 }
1988 # }}}
1989
1990 # {{{ grml2hd: automatic installation
1991 config_grml2hd(){
1992
1993 if checkbootparam "grml2hd" || checkbootparam "BOOT_IMAGE=grml2hd" ; then
1994
1995 if checkbootparam 'user' ; then
1996    NEWUSER=''
1997    NEWUSER="$(getbootparam 'user' 2>>$DEBUG)"
1998    sed -i "s/^NEWUSER=.*/NEWUSER=$NEWUSER/" /etc/grml2hd/config || export GRML2HD_FAIL=1
1999 fi
2000
2001 if checkbootparam 'filesystem' ; then
2002    FILESYSTEM=''
2003    FILESYSTEM="$(getbootparam 'filesystem' 2>>$DEBUG)"
2004    sed -i "s/^FILESYSTEM=.*/FILESYSTEM=$FILESYSTEM/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2005 fi
2006
2007 if checkbootparam 'partition' ; then
2008    PARTITION=''
2009    PARTITION="$(getbootparam 'partition' 2>>$DEBUG)"
2010    # notice: the following checks whether the given partition is available, if not the skip
2011    # execution of grml2hd as it might result in data loss...
2012    if [ -r $PARTITION ] ; then
2013       sed -i "s#^PARTITION=.*#PARTITION=$PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2014    else
2015       ewarn "Partition $PARTITION does not exist. Skipping execution of grml2hd therefore." ; eend 1
2016    fi
2017 fi
2018
2019 if checkbootparam 'mbr' ; then
2020    BOOT_PARTITION=''
2021    BOOT_PARTITION="$(getbootparam 'mbr' 2>>$DEBUG)"
2022    sed -i "s#^BOOT_PARTITION=.*#BOOT_PARTITION=$BOOT_PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2023 fi
2024
2025 cat>|/usr/bin/grml2hd_noninteractive<<EOF
2026 #!/bin/sh
2027 GRML2HD_NONINTERACTIVE='yes' grml2hd
2028 EOF
2029
2030 chmod 755 /usr/bin/grml2hd_noninteractive
2031 einfo "Bootoption grml2hd found. Running automatic installation via grml2hd using /etc/grml2hd/config." && eend 0
2032 if [ -z "$GRML2HD_FAIL" ] ; then
2033    screen /usr/bin/grml2hd_noninteractive ; einfo "Invoking a shell, just exit to continue booting..." ; /bin/zsh
2034 else
2035    ewarn "There was an error adjusting /etc/grml2hd/config. Skipping execution of grml2hd for security reasons." ; eend 1
2036 fi
2037
2038 fi # if checkbootparam "BOOT_IMAGE=grml2hd ...
2039 }
2040 # }}}
2041
2042 # {{{ debootstrap: automatic installation
2043 config_debootstrap(){
2044
2045 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
2046
2047 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
2048
2049 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
2050    eindent
2051    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
2052    eoutdent
2053    exit 1
2054 fi
2055
2056 if checkbootparam 'target' ; then
2057   TARGET=''
2058   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
2059   # notice: the following checks whether the given partition is available, if not the skip
2060   # execution of grml-debootstrap as it might result in data loss...
2061   if ! [ -r "$TARGET" ] ; then
2062      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
2063   fi
2064 else
2065   eindent
2066   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
2067   eoutdent
2068   exit 1
2069 fi
2070
2071 if checkbootparam 'grub' ; then
2072   GRUB=''
2073   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2074 fi
2075
2076 if checkbootparam 'groot' ; then
2077   GROOT=''
2078   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2079 fi
2080
2081 if checkbootparam 'release' ; then
2082   RELEASE=''
2083   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2084 fi
2085
2086 if checkbootparam 'mirror' ; then
2087   MIRROR=''
2088   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2089 fi
2090
2091 if checkbootparam 'boot_append' ; then
2092   BOOT_APPEND=''
2093   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2094 fi
2095
2096 if checkbootparam 'password' ; then
2097   PASSWORD=''
2098   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2099 fi
2100
2101 # now check which options are available
2102 if [ -n "TARGET" ] ; then
2103    TARGETCMD="--target $TARGET"
2104 else
2105    TARGETCMD=''
2106    eindent
2107    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2108    eoutdent
2109    exit 1
2110 fi
2111 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2112 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2113 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2114 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2115 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2116 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2117
2118 # and finally write script and execute it
2119 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2120 #!/bin/sh
2121 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2122 EOF
2123
2124 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2125
2126 screen /usr/bin/grml-debootstrap_noninteractive
2127 einfo "Invoking a shell, just exit to continue booting..."
2128 /bin/zsh
2129
2130 fi # checkbootparam "BOOT_IMAGE=debian2hd
2131 }
2132 # }}}
2133
2134 config_virtualbox_shared_folders() {
2135 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
2136   einfo "VirtualBox detected, trying to set up Shared Folders."
2137   if ! modprobe -l | grep -q vboxsf.ko ; then
2138     ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
2139     eend 0
2140   elif ! [ -x /usr/sbin/VBoxService ] ; then
2141     ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
2142     eend 0
2143   else
2144     eindent
2145
2146       einfo "Loading vboxsf driver."
2147       lsmod | grep -q vboxsf || modprobe vboxsf
2148       eend $?
2149
2150       einfo "Adjusting /dev/vboxguest."
2151       chown root:vboxsf /dev/vboxguest
2152       chmod 660 /dev/vboxguest
2153       eend $?
2154
2155       if [ -n "$CONFIG_FSTAB_USER" ] ; then
2156         fstabuser="$CONFIG_FSTAB_USER"
2157       else
2158         fstabuser=$(getent passwd 1000 | cut -d: -f1)
2159       fi
2160       einfo "Adding $fstabuser to group vboxsf."
2161       adduser grml vboxsf &>/dev/null
2162       eend $?
2163
2164       einfo "Starting VBoxService."
2165       VBoxService >/dev/null &
2166       eend $?
2167
2168     eoutdent
2169   fi
2170 fi
2171 }
2172
2173 # {{{ Support customization
2174 config_distri(){
2175 if checkbootparam 'distri'; then
2176   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2177   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2178      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2179      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2180      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2181      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2182   fi
2183 fi
2184 }
2185 # }}}
2186
2187 ## END OF FILE #################################################################
2188 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3