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