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