5a250405cff26fd958822d875bd3433bb3e8592d
[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
1516       modprobe 9p 2>/dev/null || true
1517       if [ -z "$DCSDEVICE" ] && grep -q 9p /proc/filesystems ; then
1518           if grep -q "$GRMLCFG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then
1519             einfo "Found 9p-virtio fs with mount_tag $GRMLCFG"
1520             DCSDEVICE="$GRMLCFG"
1521             MOUNTOPTIONS="ro,trans=virtio"
1522             DCSFS="9p"
1523           fi
1524       fi
1525
1526       if [ -n "$DCSDEVICE" ]; then
1527         DCSMP="/mnt/grmlcfg"
1528       fi
1529       eoutdent
1530     fi
1531
1532     # if not specified/present then assume default:
1533     if [ -z "$DCSDEVICE" ]; then
1534       DCSDIR="/live/image"
1535     else
1536       eindent
1537       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1538       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1539       if [ -n "$DCSDIR" ]; then
1540         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1541       else
1542         [ -d $DCSMP ] || mkdir $DCSMP
1543         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1544         mount -o ${MOUNTOPTIONS:-ro} -t ${DCSFS:-auto} $DCSDEVICE  $DCSMP ; RC="$?"
1545         if [[ $RC == 0 ]]; then
1546           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1547         else
1548           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1549         fi
1550         DCSDIR="$DCSMP"
1551       fi
1552       eoutdent
1553     fi
1554   fi
1555 fi
1556
1557 if [ -n "$DCSDIR" -a "$DCSDIR" != "/live/image" ] ; then
1558   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1559 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1560   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1561 fi
1562 }
1563
1564
1565 config_partconf() {
1566 if checkbootparam 'partconf' ; then
1567  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1568  if [ -n "$MOUNTDEVICE" ]; then
1569    [ -d /mnt/grml ] || mkdir /mnt/grml
1570    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1571     if [[ $RC == 0 ]]; then
1572       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1573       einfo "Copying files from $MOUNTDEVICE over grml system."
1574       for file in `cat /etc/grml/partconf` ; do
1575         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1576         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1577       done && eend 0
1578     else
1579       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1580     fi # mount $MOUNTDEVICE
1581    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1582  else
1583    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1584  fi # [ -n "$MOUNTDEVICE" ]
1585 fi
1586 }
1587 # }}}
1588
1589 # {{{ /cdrom/.*-options
1590 config_debs(){
1591 if checkbootparam 'debs' ; then
1592    iszsh && setopt localoptions shwordsplit
1593    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1594    if [ -z "$DEBS" ] ; then
1595       DEBS="*.deb"
1596    fi
1597    if ! echo $DEBS | grep -q '/'; then
1598      # backwards compatibility: if no path is given get debs from debs/
1599      DEBS="debs/$DEBS"
1600    fi
1601    einfo "Tring to install debian package(s) ${DEBS}"
1602    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1603    dpkg -i $DEBS ; eend $?
1604 fi
1605 }
1606
1607 config_scripts(){
1608 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1609    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1610    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1611      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1612    fi
1613    if ! echo $SCRIPTS | grep -q '/'; then
1614      # backwards compatibility: if no path is given get scripts from scripts/
1615      SCRIPTS="scripts/$SCRIPTS"
1616    fi
1617    if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1618      # we are executing from a GRMLCFG labeled fs
1619      # kick everything we have done before and start over
1620      SCRIPTS="$(cd ${DCSDIR}; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1621    fi
1622    if [ -n "$SCRIPTS" ]; then
1623      SCRIPTS="${DCSDIR}/$SCRIPTS"
1624      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1625        einfo "Trying to execute ${SCRIPTS}"
1626        sh -c $SCRIPTS
1627      elif [ -d "$SCRIPTS" ]; then
1628        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1629        run-parts $SCRIPTS
1630      else
1631        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1632        sh -c $SCRIPTS
1633      fi
1634    fi
1635 fi
1636 }
1637
1638 config_config(){
1639 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1640   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1641   if [ -z "$CONFIG" ]; then
1642     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1643   fi
1644   if [ -n "$CONFIG" ]; then
1645     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1646       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1647
1648       cp -a ${DCSDIR}/${CONFIG}/* /
1649     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1650       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1651
1652       cd /
1653       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1654     else
1655       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1656     fi
1657   fi
1658 fi
1659 }
1660 # }}}
1661
1662 # {{{ confing_umount_dcsdir
1663 config_umount_dcsdir(){
1664    # umount $DCSMP if it was mounted by finddcsdir
1665    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1666 }
1667 # }}}
1668
1669 # {{{ mypath
1670 config_mypath(){
1671 if checkbootparam 'mypath' ; then
1672    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1673    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1674    touch /etc/grml/my_path
1675    chmod 644 /etc/grml/my_path
1676    # make sure the directories exist:
1677    eindent
1678    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1679        if ! [ -d "$i" ] ; then
1680           einfo "Creating directory $i"
1681           mkdir -p "$i" ; eend $?
1682        fi
1683    done
1684    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1685    eoutdent
1686 fi
1687 }
1688 # }}}
1689
1690 # {{{ distcc
1691 config_distcc(){
1692 if checkbootparam 'distcc' ; then
1693  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
1694  if [ -n "$OPTIONS" ]; then
1695     NET=""
1696     INTERFACE=""
1697     if [ -n "$OPTIONS" ]; then
1698       NET="${OPTIONS%%,*}"
1699       R="${OPTIONS#*,}"
1700       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1701         OPTIONS="$R"
1702         INTERFACE="${OPTIONS%%,*}"
1703         R="${OPTIONS#*,}"
1704       fi
1705     fi
1706  fi
1707  CONFIG=/etc/default/distcc
1708  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
1709  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
1710
1711  if [ -n "$INTERFACE" ] ; then
1712    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1713
1714    counter=10
1715    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
1716      counter=$(( counter-1 ))
1717      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
1718      sleep 3
1719      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1720    done
1721  fi
1722
1723  if [ -n "$IP" ] ; then
1724    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
1725
1726    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
1727    eindent
1728     id distccd >/dev/null 2>&1 || \
1729     (
1730       einfo "Creating distcc user" ; \
1731       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
1732     )
1733
1734     einfo "Starting distcc for network ${NET}, listening on ${IP}."
1735    /etc/init.d/distcc start >/dev/null ; eend $?
1736    eoutdent
1737  else
1738    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
1739  fi
1740 fi
1741
1742 if checkbootparam 'gcc'; then
1743  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
1744  eindent
1745  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
1746  eoutdent
1747  rm -f /usr/bin/gcc
1748  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
1749 fi
1750
1751 if checkbootparam 'gpp'; then
1752  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
1753  eindent
1754   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
1755   if [ -x /usr/bin/g++-${GPP} ] ; then
1756      rm -f /usr/bin/g++
1757      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
1758   fi
1759   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
1760   if [ -x /usr/bin/cpp-${GPP} ] ; then
1761      rm -f /usr/bin/cpp
1762      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
1763   fi
1764  eoutdent
1765 fi
1766
1767 }
1768 # }}}
1769
1770 # {{{ load modules
1771 # Notice: use it only on live-cd system, if running from harddisk please
1772 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
1773 # in /etc/runlevel.conf
1774 config_modules(){
1775 MODULES_FILE=/etc/grml/modules
1776 if checkbootparam 'nomodules' ; then
1777   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
1778 elif [ -z "$INSTALLED" ]; then
1779  if [ -r $MODULES_FILE ] ; then
1780   einfo "Loading modules specified in ${MODULES_FILE}:"
1781   eindent
1782   grep '^[^#]' $MODULES_FILE | \
1783   while read module args; do
1784     [ "$module" ] || continue
1785       einfo "${module}"
1786       modprobe $module $args ; eend $?
1787   done
1788   eoutdent
1789  else
1790   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
1791  fi
1792 fi
1793 }
1794 # }}}
1795
1796 # {{{ SW-RAID
1797 config_swraid(){
1798   [ -n "$INSTALLED" ] && return 0
1799
1800   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
1801   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1802      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
1803      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1804   else
1805     [ -e /proc/mdstat ] || modprobe md_mod
1806     if ! [ -x /sbin/mdadm ] ; then
1807        eerror "mdadm not available, can not execute it." ; eend 1
1808     else
1809
1810        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1811        # find out whether we have a valid configuration file already
1812        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1813           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1814           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1815           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1816         else
1817           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1818        fi
1819
1820        if ! checkbootparam 'swraid' ; then
1821           eindent
1822           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1823           eoutdent
1824        else
1825           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1826           eindent
1827            IFSOLD=${IFS:-}
1828            IFS='
1829 '
1830            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
1831                case $line in
1832                  *'No arrays found'*)
1833                    ewarn "$line" ; eend 0
1834                    ;;
1835                  *)
1836                    einfo "$line" ; eend 0
1837                    ;;
1838                esac
1839            done
1840            IFS=$IFSOLD
1841          eoutdent
1842
1843          if [ -r /proc/mdstat ] ; then
1844             eindent
1845             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1846             if [ -z "$MDSTAT" ] ; then
1847                ewarn "No active arrays found" ; eend 0
1848             else
1849                IFSOLD=${IFS:-}
1850                IFS='
1851 '
1852                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1853                    einfo "active arrays: $line" ; eend 0
1854                done
1855                IFS=$IFSOLD
1856             fi
1857             eoutdent
1858          fi # /proc/mdstat
1859        fi # bootoption swraid
1860
1861      fi # is /sbin/mdadm executable?
1862   fi # check for bootoptions
1863 }
1864 # }}}
1865
1866 # {{{ dmraid
1867 config_dmraid(){
1868   [ -n "$INSTALLED" ] && return 0
1869
1870   if checkbootparam 'nodmraid' ; then
1871     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1872     return 0
1873   fi
1874
1875   if ! [ -x /sbin/dmraid ] ; then
1876     eerror "dmraid not available, can not execute it." ; eend 1
1877     return
1878   fi
1879
1880   dmraid_wrapper() {
1881     # usage: dmraid_wrapper <dmraid_option>
1882     [ -n "$1" ] || return 1
1883
1884     IFSOLD=${IFS:-}
1885     IFS='
1886 '
1887     eindent
1888
1889     for line in $(dmraid $1 ; echo errcode:$?); do
1890       case $line in
1891         *'no block devices found'*)
1892           einfo "No block devices found" ; eend 0
1893           break
1894           ;;
1895         *'no raid disks'*)
1896           einfo "No active dmraid devices found" ; eend 0
1897           break
1898           ;;
1899         errcode:0)
1900           eend 0;
1901           ;;
1902         errcode:1)
1903           eend 1
1904           ;;
1905         *)
1906           einfo "$line"
1907           ;;
1908       esac
1909     done
1910
1911     eoutdent
1912     IFS=$IFSOLD
1913   }
1914
1915   if checkbootparam 'dmraid' ; then
1916     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1917     if [ "$ACTION" = "off" ] ; then
1918       # Deactivates all active software RAID sets:
1919       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1920       dmraid_wrapper -an
1921     else
1922       # Activate all software RAID sets discovered:
1923       einfo "Activating present dmraid sets (as requested via dmraid):"
1924       dmraid_wrapper -ay
1925     fi
1926
1927     return
1928   fi
1929
1930   # by default (no special bootoptions) discover all software RAID devices:
1931   einfo "Searching for any present dmraid sets:"
1932   dmraid_wrapper -r
1933 }
1934 # }}}
1935
1936 # {{{ LVM (Logical Volumes)
1937 config_lvm(){
1938   [ -n "$INSTALLED" ] && return 0
1939
1940   if checkbootparam 'nolvm' ; then
1941      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1942   else
1943     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
1944     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
1945        eerror "LVM not available, can not execute it." ; eend 1
1946     else
1947        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1948           einfo "You seem to have logical volumes (LVM) on your system."
1949           eindent
1950           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1951           eend 0
1952           if checkbootparam 'lvm' ; then
1953              einfo "Bootoption LVM found. Searching for logical volumes:"
1954              /etc/init.d/lvm2 start ; eend $?
1955           fi
1956           eoutdent
1957        fi
1958     fi # check for lvm binary
1959   fi # check for bootoption nolvm
1960 }
1961 # }}}
1962
1963 # {{{ debnet: setup network based on an existing one found on a partition
1964 config_debnet(){
1965 if checkbootparam 'debnet' ; then
1966  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1967  /usr/sbin/debnet
1968 fi
1969 }
1970 # }}}
1971
1972 # {{{ disable console blanking
1973 config_blanking(){
1974 if checkbootparam 'noblank' ; then
1975   einfo "Bootoption noblank found. Disabling monitor blanking."
1976   setterm -blank 0 ; eend $?
1977 fi
1978 }
1979 # }}}
1980
1981 # {{{ tohd= bootoption
1982 config_tohd()
1983 {
1984   if checkbootparam 'tohd' ; then
1985      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
1986      if [ -z "$TARGET" ] ; then
1987         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
1988         eerror "Please use something like tohd=/dev/sda9." ; eend 1
1989         return 1
1990      fi
1991
1992      if ! [ -b "$TARGET" ] ; then
1993         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
1994         return 1
1995      fi
1996
1997      if grep -q $TARGET /proc/mounts ; then
1998         eerror "$TARGET already mounted, skipping execution of tohd therefore."
1999         eend 1
2000         return 1
2001      fi
2002
2003      local MOUNTDIR=$(mktemp -d)
2004
2005      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
2006         einfo "Copyring live system to $TARGET - this might take a while"
2007         rsync -a --progress /live/image/live $MOUNTDIR
2008         sync
2009         umount "$MOUNTDIR"
2010         eend $?
2011         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
2012      else
2013         eerror "Error when trying to mount $TARGET, sorry."; eend 1
2014         return 1
2015      fi
2016
2017      rmdir "$MOUNTDIR"
2018   fi
2019 }
2020 # }}}
2021
2022 # {{{ debootstrap: automatic installation
2023 config_debootstrap(){
2024
2025 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
2026
2027 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
2028
2029 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
2030    eindent
2031    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
2032    eoutdent
2033    exit 1
2034 fi
2035
2036 if checkbootparam 'target' ; then
2037   TARGET=''
2038   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
2039   # notice: the following checks whether the given partition is available, if not the skip
2040   # execution of grml-debootstrap as it might result in data loss...
2041   if ! [ -r "$TARGET" ] ; then
2042      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
2043   fi
2044 else
2045   eindent
2046   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
2047   eoutdent
2048   exit 1
2049 fi
2050
2051 if checkbootparam 'grub' ; then
2052   GRUB=''
2053   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2054 fi
2055
2056 if checkbootparam 'groot' ; then
2057   GROOT=''
2058   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2059 fi
2060
2061 if checkbootparam 'release' ; then
2062   RELEASE=''
2063   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2064 fi
2065
2066 if checkbootparam 'mirror' ; then
2067   MIRROR=''
2068   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2069 fi
2070
2071 if checkbootparam 'boot_append' ; then
2072   BOOT_APPEND=''
2073   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2074 fi
2075
2076 if checkbootparam 'password' ; then
2077   PASSWORD=''
2078   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2079 fi
2080
2081 # now check which options are available
2082 if [ -n "TARGET" ] ; then
2083    TARGETCMD="--target $TARGET"
2084 else
2085    TARGETCMD=''
2086    eindent
2087    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2088    eoutdent
2089    exit 1
2090 fi
2091 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2092 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2093 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2094 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2095 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2096 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2097
2098 # and finally write script and execute it
2099 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2100 #!/bin/sh
2101 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2102 EOF
2103
2104 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2105
2106 screen /usr/bin/grml-debootstrap_noninteractive
2107 einfo "Invoking a shell, just exit to continue booting..."
2108 /bin/zsh
2109
2110 fi # checkbootparam "BOOT_IMAGE=debian2hd
2111 }
2112 # }}}
2113
2114 config_virtualbox_shared_folders() {
2115 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
2116   einfo "VirtualBox detected, trying to set up Shared Folders."
2117   if ! modprobe -l | grep -q vboxsf.ko ; then
2118     ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
2119     eend 0
2120   elif ! [ -x /usr/sbin/VBoxService ] ; then
2121     ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
2122     eend 0
2123   else
2124     eindent
2125
2126       einfo "Loading vboxsf driver."
2127       lsmod | grep -q vboxsf || modprobe vboxsf
2128       eend $?
2129
2130       einfo "Adjusting /dev/vboxguest."
2131       chown root:vboxsf /dev/vboxguest
2132       chmod 660 /dev/vboxguest
2133       eend $?
2134
2135       if [ -n "$CONFIG_FSTAB_USER" ] ; then
2136         fstabuser="$CONFIG_FSTAB_USER"
2137       else
2138         fstabuser=$(getent passwd 1000 | cut -d: -f1)
2139       fi
2140       einfo "Adding $fstabuser to group vboxsf."
2141       adduser grml vboxsf &>/dev/null
2142       eend $?
2143
2144       einfo "Starting VBoxService."
2145       VBoxService >/dev/null &
2146       eend $?
2147
2148     eoutdent
2149   fi
2150 fi
2151 }
2152
2153 # {{{ Support customization
2154 config_distri(){
2155 if checkbootparam 'distri'; then
2156   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2157   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2158      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2159      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2160      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2161      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2162   fi
2163 fi
2164 }
2165 # }}}
2166
2167 ## END OF FILE #################################################################
2168 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3