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