Added random hostname support. Thanks to Gregor Perner for the idea.
[grml-autoconfig.git] / autoconfig.functions
1 #!/bin/zsh
2 # Filename:      autoconfig.functions
3 # Purpose:       basic system configuration and hardware setup for grml system
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 ################################################################################
8
9 # {{{ path, variables, signals, umask, zsh
10 export PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin"
11 DEBUG="/dev/null"
12 KERNEL="$(uname -r)"
13 ARCH="$(uname -m)"
14 umask 022
15
16 # old linuxrc version:
17 [ -d /cdrom ]      && export LIVECD_PATH=/cdrom
18 # new initramfs layout:
19 [ -d /live/image ] && export LIVECD_PATH=/live/image
20
21 # Ignore these signals in non-interactive mode: INT, TERM, SEGV
22 [ -z "$PS1" ] && trap "" 2 3 11
23
24 # zsh stuff
25 iszsh(){
26 if [ -n "$ZSH_VERSION" ] ; then
27   return 0
28 else
29   return 1
30 fi
31 }
32 # avoid 'no matches found: ...'
33 iszsh && setopt no_nomatch # || echo "Warning: not running under zsh!"
34 # }}}
35
36 # {{{ Read in boot parameters
37 if [ -z "$CMDLINE" ]; then
38   # if CMDLINE was set from the outside, we're debugging.
39   # otherwise, take CMDLINE from Kernel and config files.
40   CMDLINE="$(cat /proc/cmdline)"
41   [ -d /cdrom/bootparams/ ]      && CMDLINE="$CMDLINE $(cat /cdrom/bootparams/* | tr '\n' ' ')"
42   [ -d /live/image/bootparams/ ] && CMDLINE="$CMDLINE $(cat /live/image/bootparams/* | tr '\n' ' ')"
43 fi
44 # }}}
45
46 ### {{{ Utility Functions
47
48 # Get a bootoption's parameter: read boot command line and either
49 # echo last parameter's argument or return false.
50 getbootparam(){
51   local line
52   local ws
53   ws='   '
54   line=" $CMDLINE "
55   case "$line" in
56     *[${ws}]"$1="*)
57       result="${line##*[$ws]$1=}"
58       result="${result%%[$ws]*}"
59       echo "$result"
60       return 0 ;;
61     *) # no match?
62       return 1 ;;
63   esac
64 }
65
66 # Check boot commandline for specified option
67 checkbootparam(){
68   [ -n "$1" ] || ( echo "Error: missing argument to checkbootparam()" ; return 1 )
69   local line
70   local ws
71   ws='   '
72   line=" $CMDLINE "
73   case "$line" in
74     *[${ws}]"$1"=*|*[${ws}]"$1"[${ws}]*)
75       return 0 ;;
76     *)
77       return 1 ;;
78   esac
79 }
80
81 # Check if currently using a framebuffer
82 hasfb() {
83     [ -e /dev/fb0 ] && return 0 || return 1
84 }
85
86 # Check wheter a configuration variable (like $CONFIG_TOHD) is
87 # enabled or not
88 checkvalue(){
89   case "$1" in
90     [yY][eE][sS])     return 0 ;; # it's set to 'yes'
91     [tT][rR][uU][eE]) return 0 ;; # it's set to 'true'
92                    *) return 1 ;; # default
93   esac
94 }
95
96 # Are we using grml-small?
97 checkgrmlsmall(){
98   grep -q small /etc/grml_version 2>>$DEBUG && return 0 || return 1
99 }
100
101 # execute flite only if it's present
102 flitewrapper() {
103    [ -x /usr/bin/flite ] && flite -o play -t "$*"
104 }
105 ### }}}
106
107 # {{{ filesystems (proc, pts, sys) and fixes
108 mount_proc(){
109   [ -f /proc/version ] || mount -t proc /proc /proc 2>/dev/null
110 }
111
112 mount_pts(){
113   grep -q "/dev/pts" /proc/mounts || mount -t devpts /dev/pts /dev/pts 2>/dev/null
114 }
115
116 mount_sys(){
117   [ -d /sys/devices ] || mount -t sysfs /sys /sys 2>/dev/null
118 }
119 # }}}
120
121 # {{{ Check if we are running in live mode or from HD
122 INSTALLED=""
123 [ -e /etc/grml_cd ] || INSTALLED="yes"
124
125 # testcd
126 TESTCD=""
127 checkbootparam 'testcd' >>$DEBUG 2>&1 && TESTCD="yes"
128 # }}}
129
130 # {{{ source lsb-functions , color handling
131 if checkbootparam 'nocolor'; then
132   RC_NOCOLOR=yes
133   . /etc/grml/lsb-functions
134   einfo "Disabling colors in bootsequence as requested on commandline." ; eend 0
135 else
136   . /etc/grml/lsb-functions
137   . /etc/grml_colors
138 fi
139 # }}}
140
141 # {{{ debug
142 config_debug(){
143  checkbootparam 'debug'            && BOOTDEBUG="yes"
144  checkbootparam "BOOT_IMAGE=debug" && BOOTDEBUG="yes"
145
146  rundebugshell(){
147   if [ -n "$BOOTDEBUG" ]; then
148      einfo "Starting intermediate shell stage $stage as requested by \"debug\" option."
149      if [ grep -q "debug=noscreen" "$CMDLINE" ] ; then
150         einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
151         einfo "Just exit the shell to continue boot process..."
152         /bin/zsh
153      else
154         eindent
155         if [ -r /etc/grml/screenrc ] ; then
156            einfo "Starting GNU screen to be able to use a full featured shell environment."
157            einfo "Just exit the shells (and therefore screen) to continue boot process..."
158            /bin/zsh -c "screen -c /etc/grml/screenrc"
159         else
160            einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
161            einfo "Just exit the shell to continue boot process..."
162            /bin/zsh
163         fi
164         eoutdent
165      fi
166   fi
167  }
168 }
169 # }}}
170
171 # {{{ log
172 config_log(){
173 if checkbootparam 'log' || checkbootparam 'debug' ; then
174    export DEBUG="/tmp/grml.log.`date +%Y%m%d`"
175    touch $DEBUG
176    einfo "Bootparameter log found. Log files: ${DEBUG} and /var/log/boot"
177    eindent
178      einfo "Starting bootlogd." # known to be *very* unreliable :(
179      bootlogd -r -c >>$DEBUG 2>&1 ; eend $?
180    eoutdent
181 else
182    DEBUG="/dev/null"
183 fi
184 }
185 # }}}
186
187 # {{{ set firmware timeout via bootparam
188 config_fwtimeout(){
189  if checkbootparam 'fwtimeout' ; then
190    TIMEOUT="$(getbootparam 'fwtimeout' 2>>$DEBUG)"
191    einfo "Bootoption fwtimeout found. (Re)Loading firmware_class module."
192    rmmod firmware_class >>$DEBUG 2>&1
193    modprobe firmware_class ; eend $?
194  fi
195  if [ -z "$TIMEOUT" ] ; then
196    TIMEOUT="100" # linux kernel default: 10
197  fi
198  if [ -f /sys/class/firmware/timeout ] ; then
199    einfo "Setting timeout for firmware loading to ${TIMEOUT}."
200    echo 100 > /sys/class/firmware/timeout ; eend $?
201  fi
202 }
203 # }}}
204
205 ### {{{ language configuration / localization
206 config_language(){
207
208  einfo "Activating language settings:"
209  eindent
210
211  # people can specify $LANGUAGE and $CONSOLEFONT in a config file
212  [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
213
214  # check for bootoption which overrides config from /etc/grml/autoconfig
215  BOOT_LANGUAGE="$(getbootparam 'lang' 2>>$DEBUG)"
216  [ -n "$BOOT_LANGUAGE" ] && LANGUAGE="$BOOT_LANGUAGE"
217
218  # set default to 'en' in live-cd mode iff $LANGUAGE is not set yet
219  if [ -z "$INSTALLED" ] ; then
220     [ -n "$LANGUAGE" ] || LANGUAGE='en'
221  fi
222
223  if [ -x /usr/sbin/grml-setlang ] ; then
224    # if bootoption lang is used update /etc/default/locale accordingly
225    if [ -n "$BOOT_LANGUAGE" ] ; then
226      checkgrmlsmall && /usr/sbin/grml-setlang "POSIX" || /usr/sbin/grml-setlang "$LANGUAGE"
227    # otherwise default to lang=en
228    else
229      checkgrmlsmall && /usr/sbin/grml-setlang "POSIX" || /usr/sbin/grml-setlang "en"
230    fi
231  fi
232
233  # set console font
234  if [ -z "$CONSOLEFONT" ] ; then
235     if ! checkbootparam 'nodefaultfont' >>$DEBUG 2>&1 ; then
236        if [ -r /usr/share/consolefonts/Uni3-Terminus16.psf.gz ] ; then
237           CONSOLEFONT='Uni3-Terminus16'
238        else
239           ewarn "/usr/share/consolefonts/Uni3-Terminus16.psf.gz not available. Please upgrade package console-terminus." ; eend 1
240        fi
241        if ! hasfb ; then
242           CONSOLEFONT='Lat15-Terminus16'
243        fi
244     fi
245  fi
246
247  # export it now, so error messages get translated, too
248  if checkgrmlsmall ; then
249     export LANG='C' # grml-small does not provide any further locales
250  else
251     [ -r /etc/default/locale ] && . /etc/default/locale
252     export LANG LANGUAGE
253  fi
254
255  # configure keyboard layout, read in already set values first:
256  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
257
258  # now allow keyboard override by boot commandline for later use:
259  KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
260  [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
261  # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
262  [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
263  [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
264
265  # modify /etc/sysconfig/keyboard only in live-cd mode:
266  if [ -z "$INSTALLED" ] ; then
267
268    local LANGUAGE="$BOOT_LANGUAGE"
269    . /etc/grml/language-functions
270    # allow setting xkeyboard explicitly different than console keyboard
271    KXKEYBOARD="$(getbootparam 'xkeyboard' 2>>$DEBUG)"
272    if [ -n "$KXKEYBOARD" ]; then
273       XKEYBOARD="$KXKEYBOARD"
274       KDEKEYBOARD="$KXKEYBOARD"
275    elif [ -n "$KKEYBOARD" ]; then
276       XKEYBOARD="$KKEYBOARD"
277       KDEKEYBOARD="$KKEYBOARD"
278    fi
279
280    # duplicate of previous code to make sure /etc/grml/language-functions
281    # does not overwrite our values....
282    # now allow keyboard override by boot commandline for later use:
283    KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
284    [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
285    # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
286    [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
287    [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
288
289    # write keyboard related variables to file for later use
290    [ -d /etc/sysconfig ] || mkdir /etc/sysconfig
291    if ! [ -e /etc/sysconfig/keyboard ] ; then
292       echo "KEYTABLE=\"$KEYTABLE\""          > /etc/sysconfig/keyboard
293       echo "XKEYBOARD=\"$XKEYBOARD\""       >> /etc/sysconfig/keyboard
294       echo "KDEKEYBOARD=\"$KDEKEYBOARD\""   >> /etc/sysconfig/keyboard
295       echo "KDEKEYBOARDS=\"$KDEKEYBOARDS\"" >> /etc/sysconfig/keyboard
296    fi
297  fi
298
299  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
300
301  # activate unicode console if running within utf8 environment
302  if [ -r /etc/default/locale ] ; then
303     if grep -q "LANG=.*UTF" /etc/default/locale ; then
304        einfo "Setting up unicode environment."
305        unicode_start >>$DEBUG 2>&1 ; eend $?
306     fi
307  fi
308
309  # Set default keyboard before interactive setup
310  if [ -n "$KEYTABLE" ] ; then
311     einfo "Running loadkeys for ${WHITE}${KEYTABLE}${NORMAL} in background"
312     loadkeys -q $KEYTABLE &
313     eend $?
314  fi
315
316  # we have to set up all consoles, therefore loop it over all ttys:
317  NUM_CONSOLES=$(fgconsole --next-available 2>/dev/null)
318  if [ -n "$NUM_CONSOLES" ] ; then
319     NUM_CONSOLES=$(expr ${NUM_CONSOLES} - 1)
320     [ ${NUM_CONSOLES} -eq 1 ] && NUM_CONSOLES=6
321  fi
322  CUR_CONSOLE=$(fgconsole 2>/dev/null)
323  if [ -n "$CHARMAP" ] ; then
324     einfo "Running consolechars for ${CHARMAP}"
325     RC=0
326     for vc in $(seq 0 ${NUM_CONSOLES}) ; do
327         consolechars --tty=/dev/tty${vc} -m ${CHARMAP} ; RC=$?
328     done
329     if [ -n "$CUR_CONSOLE" ] ; then
330        [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
331     fi
332     eend $RC
333  fi
334
335  if checkbootparam 'noconsolefont' ; then
336     ewarn "Skipping setting console font as requested on boot commandline." ; eend 0
337  else
338     if [ -n "$CONSOLEFONT" ] ; then
339        einfo "Running consolechars using ${CONSOLEFONT}"
340        RC=0
341        for vc in $(seq 0 ${NUM_CONSOLES}) ; do
342            consolechars --tty=/dev/tty${vc} -f $CONSOLEFONT ; RC=$?
343        done
344        if [ -n "$CUR_CONSOLE" ] ; then
345           [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
346        fi
347        eend $RC
348     fi
349  fi
350
351  eoutdent
352 }
353 # }}}
354
355 # {{{ Set hostname
356 config_hostname(){
357  if checkbootparam 'hostname' ; then
358   HOSTNAME="$(getbootparam 'hostname' 2>>$DEBUG)"
359   if [ -z "$HOSTNAME" ] && [ -x /usr/bin/random-hostname ] ; then
360      einfo "Generating random hostname as no hostname was specified"
361      HOSTNAME="$(/usr/bin/random-hostname)"
362   fi
363   einfo "Setting hostname to $HOSTNAME as requested."
364   grml-hostname $HOSTNAME >>$DEBUG ; RC=$?
365   [ "$RC" = "0" ] && hostname $HOSTNAME
366   eend $RC
367  else
368   hostname --file /etc/hostname
369  fi
370 }
371 # }}}
372
373 # fstabuser (needed when running from harddisk with username != grml {{{
374 config_userfstab(){
375   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
376   if [ -n "$CONFIG_FSTAB_USER" ] ; then
377      fstabuser="$CONFIG_FSTAB_USER"
378   else
379      fstabuser=$(getent passwd 1000 | cut -d: -f1)
380   fi
381   # if not yet set fall back to default 'grml' user
382   [ -n "$fstabuser" ] || fstabuser='grml'
383 }
384 # }}}
385
386 # {{{ Set clock (Local time is more often used than GMT, so it is default)
387 config_time(){
388  # don't touch the files if running from harddisk:
389  if [ -z "$INSTALLED" ]; then
390     # The default hardware clock timezone is stated as representing local time.
391     UTC="--localtime"
392     grep -q "^UTC=" /etc/default/rcS || echo "UTC=no" >> /etc/default/rcS
393     checkbootparam 'utc'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
394     checkbootparam 'gmt'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
395     checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=no|"  /etc/default/rcS
396     grep -q -i "^UTC=yes" /etc/default/rcS && UTC="-u"
397     # hwclock uses the TZ variable
398     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
399     [ -z "$KTZ" ] && [ -r /etc/timezone ] && KTZ=$(cat /etc/timezone)
400     if [ ! -f "/usr/share/zoneinfo/$KTZ" ] ; then
401        ewarn "Warning: unknown timezone $KTZ" ; eend 1
402        KTZ="Europe/Vienna"
403        ewarn "Falling back to timezone $KTZ" ; eend 0
404     fi
405
406     if ! [ -r /dev/rtc ] ; then
407       ewarn "Warning: realtime clock not available, trying to execute hwclock anyway." ; eend 0
408     fi
409
410     ERROR=$(TZ="$KTZ" hwclock $UTC -s 2>&1 | head -1) ; RC=$?
411     if [ -n "$ERROR" ] ; then
412        eindent
413        ERROR=$(TZ="$KTZ" hwclock $UTC -s --directisa 2>&1 | head -1)
414        if [ -n "$ERROR" ] ; then
415           eerror "Problem running hwclock: $ERROR" ; eend 1
416        fi
417        eoutdent
418     fi
419
420  fi
421 }
422 # }}}
423
424 # {{{ print kernel info
425 config_kernel(){
426   vmware-detect &>/dev/null && VMWARE="inside ${WHITE}VMware/Qemu${NORMAL}"
427   [ -d /proc/xen ] && VMWARE='' # vmware-detect returns '0' when running with a Xen-enabled kernel
428   einfo "Running Linux Kernel $KERNEL $VMWARE" ; eend 0
429   if [ -r /proc/cpuinfo ] ; then
430      if egrep -q '^flags.*(vmx|svm)' /proc/cpuinfo ; then
431        eindent
432        einfo 'CPU(s) featuring virtualization technology detected' ; eend 0
433        eoutdent
434      fi
435   fi
436   if [ -d /proc/xen ] ; then
437      eindent
438      einfo 'Running kernel featuring support for Xen detected' ; eend 0
439      eoutdent
440   fi
441 }
442 # }}}
443
444 # {{{ vmware specific stuff
445 config_vmware(){
446 if checkbootparam 'novmware' ; then
447    ewarn "Skipping running vmware specific stuff as requested on boot commandline." ; eend 0
448 else
449    if [ -z "$INSTALLED" ] ; then
450       if vmware-detect || checkbootparam "BOOT_IMAGE=vmware" ; then
451          if ! checkbootparam 'qemu' ; then
452             if [ -r /etc/X11/xorg.conf.vmware ] ; then
453                einfo "VMware: Copying /etc/X11/xorg.conf.vmware to /etc/X11/xorg.conf"
454                cp /etc/X11/xorg.conf.vmware /etc/X11/xorg.conf ; eend $?
455             fi
456          fi
457       elif [ -r /proc/acpi/battery/BAT0/info -a -r /etc/X11/xorg.conf.virtualbox ] ; then
458          if grep -q 'OEM info:                innotek' /proc/acpi/battery/BAT0/info ; then
459             einfo 'Virtual Box: Copying /etc/X11/xorg.conf.virtualbox to /etc/X11/xorg.conf'
460             cp /etc/X11/xorg.conf.virtualbox /etc/X11/xorg.conf ; eend $?
461          fi
462       fi
463    fi
464 fi
465 }
466 # }}}
467
468 # {{{ qemu specific stuff
469 config_qemu(){
470 if checkbootparam 'qemu' ; then
471    if [ -r /etc/X11/xorg.conf.example ] ; then
472       einfo "Qemu: Copying /etc/X11/xorg.conf.example to /etc/X11/xorg.conf"
473       cp /etc/X11/xorg.conf.example /etc/X11/xorg.conf ; eend $?
474    fi
475 fi
476 }
477 # }}}
478
479 # {{{ ld.so.cache + depmod
480 config_ld_mod(){
481 if [ -n "$INSTALLED" ]; then
482  if ! [ -r /etc/grml.first.boot ] ; then
483   einfo "Running from HD for the first time, regenerate ld.so.cache and modules.dep:"
484   eindent
485 # Regenerate ld.so.cache and module dependencies on HD
486     einfo "Running ldconfig" ; ldconfig  ; eend $?
487     einfo "Running depmod"   ; depmod -a ; eend $?
488     touch /etc/grml.first.boot
489     eend 0
490   eoutdent
491  fi
492 fi
493 }
494 # }}}
495
496 # {{{ timezone
497 config_timezone(){
498  # don't touch the files if running from harddisk:
499  if [ -z "$INSTALLED" ]; then
500     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
501     if [ -n "$KTZ" ] ; then
502        if [ ! -f "/usr/share/zoneinfo/$KTZ" ]
503        then
504           ewarn "Warning: unknown timezone $KTZ"; eend 0
505        else
506           einfo "Setting timezone."
507           # update debconf
508           area=$(echo $KTZ | cut -d '/' -f1)
509           zone=$(echo $KTZ | cut -d '/' -f2)
510           echo "tzdata tzdata/Areas       select $area" | debconf-set-selections
511           echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections
512           # update files
513           echo $KTZ > /etc/timezone
514           rm -f /etc/localtime
515           cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $?
516        fi
517     fi
518  fi
519 }
520 # }}}
521
522 # small computer / nearly no ram {{{
523 config_small(){
524
525 RAM=$(/usr/bin/gawk '/MemTotal/{print $2}' /proc/meminfo)
526 # MEM=$(/usr/bin/gawk 'BEGIN{m=0};/MemFree|Cached|SwapFree/{m+=$2};END{print m}' /proc/meminfo)
527 eindent
528
529 if checkbootparam 'small'; then
530   einfo "Information: ${RAM} kB of RAM available." ; eend 0
531   einfo "Bootoption small detected. Activating small system."
532   if [ -r /etc/inittab.small ] ; then
533     mv /etc/inittab /etc/inittab.normal
534     mv /etc/inittab.small /etc/inittab
535   else
536     sed -i 's/^9/#&/' /etc/inittab
537     sed -i 's/^10/#&/' /etc/inittab
538     sed -i 's/^11/#&/' /etc/inittab
539     sed -i 's/^12/#&/' /etc/inittab
540   fi
541   /sbin/telinit q ; eend $?
542 else
543   if checkgrmlsmall ; then
544     if [[ $RAM -lt 25000 ]] ; then
545       ewarn "Information: ${RAM} kB of RAM available." ; eend 1
546       ewarn "At least 32MB of RAM should be available for grml-small." ; eend 1
547       ewarn "Use the bootoption small to save some more MB of memory usage." ; eend 0
548       ewarn "Dropping you into a rescue shell. To continue booting exit the shell." ; eend 0
549       /bin/zsh --login
550     else
551       einfo "Information: ${RAM} kB of RAM available." ; eend 0
552     fi
553   else
554     if [[ $RAM -lt 58000 ]] ; then
555       ewarn "Information: ${RAM} kB of RAM available." ; eend 1
556       ewarn "At least 64MB of RAM should be available for grml." ; eend 1
557       ewarn "Use the bootoption small to save some more MB of memory usage." ; eend 0
558       ewarn "Dropping you into a rescue shell. To continue booting exit the shell." ; eend 0
559       /bin/zsh --login
560     else
561       einfo "Information: ${RAM} kB of RAM available." ; eend 0
562     fi
563   fi
564 fi
565 eoutdent
566 }
567 # }}}
568
569 # skip startup of w3m {{{
570 config_fast(){
571 if checkbootparam 'fast'; then
572   ewarn "Bootoption fast detected. Skipping startup of grml-quickconfig."
573     sed -i 's#^1:.*#1:12345:respawn:/usr/bin/openvt -f -c 1 -w -- /bin/zsh#' /etc/inittab
574   /sbin/telinit q ; eend $?
575 fi
576 }
577 # }}}
578
579 # activate serial console {{{
580 config_console(){
581 if checkbootparam 'console'; then
582   local line
583   local ws
584   ws='   '
585
586   einfo "Bootoption for serial console detected:"
587
588   line="$CMDLINE x "
589   this=""
590   line="${line#*[$ws]}"
591   local telinitq=""
592   while [ -n "$line" ]; do
593     case "$this" in
594       console=*)
595         local serial="$this"
596         local device="${this%%,*}"
597         local device="${device##*=}"
598         if ! echo $serial | grep -q ttyS ; then
599           ewarn "Warning: console=ttyS... not specified as last console= option. Falling back to set up ttyS0/9600."
600           sed -i "/^#grmlserial#/iT0:23:respawn:/bin/bash -c \"/sbin/getty -L /dev/ttyS0 -l /usr/bin/zsh-login 9600 vt100 || sleep 30\"" /etc/inittab
601           eend 0
602         else
603           local option="${serial##*,}"
604           # default (works for kvm & CO):
605           local speed="115200,57600,38400,19200,9600,4800,2400,1200";
606           # ... unless overriden by command line:
607           case "$option" in
608             115200*) speed=115200 ;;
609              57600*) speed=57600 ;;
610              38400*) speed=38400 ;;
611              19200*) speed=19200 ;;
612               9600*) speed=9600 ;;
613               4800*) speed=4800 ;;
614               2400*) speed=2400 ;;
615               1200*) speed=1200 ;;
616           esac
617         fi
618         eindent
619           einfo "Activating console login on device ${device} with speed ${speed}."
620           local number="${device#ttyS}"
621           sed -i "/^#grmlserial#/iT$number:23:respawn:/bin/bash -c \"/sbin/getty -L $device -l /usr/bin/zsh-login $speed vt100 || sleep 30\"" /etc/inittab
622           eend $?
623           telinitq="1"
624         eoutdent
625         ;;
626     esac
627     this="${line%%[$ws]*}"
628     line="${line#*[$ws]}"
629   done
630
631   if [ -n "$telinitq" ]; then
632     /sbin/telinit q
633   fi
634   eend $?
635 fi
636 }
637 # }}}
638
639 # For burning on IDE-CD-Roms, k3b (and others) check for special permissions {{{
640 config_cdrom_perm(){
641 CDROMS=""
642 for DEVICE in /proc/ide/hd?; do
643  [ "$(cat $DEVICE/media 2>/dev/null)" = "cdrom" ] && CDROMS="$CDROMS /dev/${DEVICE##*/}"
644 done
645 [ -n "$CDROMS" ] && { chown root.cdrom $CDROMS; chmod 666 $CDROMS; } 2>/dev/null
646 }
647 # }}}
648
649 # {{{ Bring up loopback interface now
650 config_local_net(){
651  if [ -z "$INSTALLED" ] ; then
652     if grep -q 'iface lo inet loopback' /etc/network/interfaces 2>/dev/null ; then
653        grep -q lo=lo /etc/network/run/ifstate 2>/dev/null || ifup lo
654     else
655        ifconfig lo up
656     fi
657  fi
658 }
659 # }}}
660
661 # firewire devices {{{
662 # the raw1394 driver does not yet export info into SYSFS,
663 # so let's create raw1394 device manually
664 # http://www.michael-prokop.at/blog/index.php?p=352
665 config_firewire_dev(){
666 if checkbootparam 'nofirewiredev' ; then
667   ewarn "Skipping creating some firewire devices as requested on boot commandline." ; eend 0
668 else
669 #if [ "${KERNEL%-*}" == "2.6.11" ] ; then
670   einfo "Creating some firewire devices (fix kernel 2.6-bug)."
671 #  cd /dev && MAKEDEV video1394 raw1394
672   [ -r /dev/raw1394 ]   || mknod /dev/raw1394 c 171 0
673   [ -r /dev/video1394 ] || mknod -m 666 /dev/video1394 c 171 16
674 # mknod -m 666 /dev/dv1394 c 171 32 # for NTSC
675   [ -r /dev/dv1394 ]    || mknod -m 666 /dev/dv1394 c 171 34 # for PAL
676   chown -R root:video /dev/raw1394 /dev/video1394 /dev/dv1394
677   chmod -R 664 /dev/raw1394 /dev/video1394 /dev/dv1394 ; eend $?
678 fi
679 #fi
680 }
681 # }}}
682
683 # {{{ copy passwd-lockfile to ramdisk (fix unionfs-behaviour)
684 # otherwise we will get: passwd: Authentication token lock busy
685 config_fix_passwd(){
686  if [ -z "$INSTALLED" ] ; then
687   touch /etc/.pwd.lock
688  fi
689 }
690 # }}}
691
692 # {{{ CD Checker
693 config_testcd(){
694 if [ -n "$TESTCD" ]; then
695    einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
696    einfo "Reading files and checking against GRML/md5sums, this may take a while..."
697    echo -n "${RED}"
698
699    if [ -n "${LIVECD_PATH}"/GRML ] ; then
700       ( cd "${LIVECD_PATH}"/GRML ; rm -f /tmp/md5sum.log ; md5sum -c md5sums 2>&1 | tee /tmp/md5sum.log ; RC=$? )
701    else
702       echo "${RED} *** Error: Could not find md5sum file.                           ***"
703    fi
704
705    if [ "$RC" = "0" ]; then
706       einfo "Everything looks OK" ; eend 0
707    else
708       eerror 'Checksum failed for theses files:' ; eend 1
709       egrep -v '(^md5sum:|OK$)' /tmp/md5sum.log
710       eerror 'Data on the grml medium is possibly incomplete/damaged or...'
711       eerror '... RAM of your computer is broken.' ; eend 1
712       einfon "Hit return to continue, or press the reset button to quit."
713      read a
714    fi
715
716    eend 0
717 fi
718 }
719 # }}}
720
721 # {{{ hardware detection via discover
722 config_discover(){
723 if checkbootparam 'nodisc' ; then
724   ewarn "Skipping hardware detection via discover as requested on boot commandline." ; eend 0
725 else
726  if [ -x /sbin/discover ] ; then
727   einfo "Discovering hardware. Trying to load the following modules in background:"
728    eindent
729    einfo "$(discover --data-path=linux/module/name --data-path=linux/modules/options --format="%s %s" --data-version=`uname -r` --enable-bus all | sort -u | xargs echo)"
730    eoutdent
731   /sbin/discover-modprobe -v >>$DEBUG 2>&1 &
732   eend 0
733  else
734   eerror "Application discover not available. Information: udev should handle hardware recognition." ; eend 0
735  fi
736 fi
737 }
738 # }}}
739
740 # {{{ hardware detection via hwinfo
741 config_hwinfo(){
742 if checkbootparam 'hwinfo' >>$DEBUG 2>&1; then
743   einfo "Discovering hardware via hwinfo:"
744   MODULES=$(su grml hwinfo | grep "Cmd: \"modprobe" | awk '{print $5}' | sed 's/"//')
745   echo -n "  Loading modules: "
746   for i in `echo $MODULES` ; do echo -n $i && modprobe $i ; done
747   eend 0
748 fi
749 }
750 # }}}
751
752 # {{{ disable hotplug agents on request
753 config_hotplug_agent(){
754 if checkbootparam 'noagent' ; then
755   AGENT="$(getbootparam 'noagent' 2>>$DEBUG)"
756   AGENTLIST=$(echo "$AGENT" | sed 's/,/\\n/g')
757   AGENTNL=$(echo "$AGENT" | sed 's/,/ /g')
758   einfo "Disabling hotplug-agent(s) $AGENTNL"
759   for agent in $(echo -e $AGENTLIST) ; do
760     mv /etc/hotplug/${agent}.rc /etc/hotplug/${agent}.norc
761   done
762   [ "$?" == "0" ] ; eend $?
763 fi
764 }
765 # }}}
766
767 # {{{ blacklist of hotplug-modules
768 config_hotplug_blacklist(){
769 if checkbootparam 'black' ; then
770   BLACK="$(getbootparam 'black' 2>>$DEBUG)"
771   BLACKLIST=$(echo "$BLACK" | sed 's/,/\\n/g')
772   BLACKNL=$(echo "$BLACK" | sed 's/,/ /g')
773   einfo "Blacklisting $BLACKNL via /etc/hotplug/blacklist.d/hotplug-light"
774   echo -e "$BLACKLIST" >> /etc/hotplug/blacklist.d/hotplug-light
775   echo -e "$BLACKLIST" >> /etc/hotplug/blacklist
776   eend 0
777 fi
778 }
779 # }}}
780
781 # {{{ run hotplug
782 config_hotplug(){
783 if checkbootparam 'nohotplug' ; then
784   ewarn "Skipping running hotplug as requested on boot commandline." ; eend 0
785 else
786   if [ -r /etc/init.d/hotplug ] ; then
787     einfo "Starting hotplug system in background."
788     /etc/init.d/hotplug start >>$DEBUG 2>>$DEBUG &
789     eend 0
790   elif [ -r /etc/init.d/hotplug-light ] ; then
791     einfo "Starting hotplug-light system in background."
792     /etc/init.d/hotplug-light start >>$DEBUG 2>>$DEBUG &
793     eend 0
794   else
795     ewarn "No hotplug system found. Should be handled by udev. Skipping execution." ; eend 0
796   fi
797 fi
798 }
799 # }}}
800
801 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
802 config_blacklist(){
803 if checkbootparam 'blacklist' ; then
804  if [ -z "$INSTALLED" ]; then
805   einfo "Bootoption blacklist found."
806   BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
807   BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
808   if [ -n "$BLACK" ] ; then
809     for module in $(echo ${BLACK//,/ }) ; do
810         einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
811         echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
812         echo "blacklist $module"     >> "$BLACKLIST_FILE"
813         echo "alias     $module off" >> "$BLACKLIST_FILE"
814         echo "# end   entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
815     done
816   else
817    eerror "No given module for blacklist found. Blacklisting will not work therefore."
818   fi
819  else
820   ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
821   eindent
822    einfo "Please blacklist the module(s) manually using the 'blacklist' script."
823   eoutdent
824  fi
825 fi
826 }
827 # }}}
828
829 # {{{ ACPI
830 config_acpi_apm(){
831 if [ -d /proc/acpi ]; then
832   if checkbootparam 'noacpi'; then
833     ewarn "Skipping ACPI Bios detection as requested via noacpi on boot commandline." ; eend 0
834   elif checkbootparam 'nogrmlacpi' ; then
835     ewarn "Skipping ACPI Bios detection as requested via nogrmlacpi on boot commandline." ; eend 0
836   else
837     einfo "ACPI Bios found, activating modules (disable via bootoption noacpi / nogrmlacpi): "
838     eindent
839     found=""
840     for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
841       basename="${a##*/}"
842       basename="${basename%%.*}"
843       case "$basename" in *_acpi)
844        egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
845       esac
846       modprobe $basename >>$DEBUG 2>&1 && found="yes"
847       local BASE="$BASE $basename"
848     done
849     if [ -n "$found" ] ; then
850       einfo "$BASE"  ; eend 0
851     else
852       ewarn "(none)" ; eend 1
853     fi
854     if ! ps x | grep -q /usr/sbin/acpid ; then
855       if ! [ -r /var/run/dbus/pid ] ; then
856         einfo "Starting acpi daemon."
857         /etc/init.d/acpid start >>$DEBUG 2>&1 ; eend $?
858       else
859         eerror "acpid error: it seems you are running d-bus/hal, but acpid needs to be started before d-bus."
860         eerror "Solution: please activate acpid via /etc/runlevel.conf"
861         eend 1
862       fi
863     else
864       ewarn "acpi daemon already running."
865       eend 0
866     fi
867     eoutdent
868   fi
869 else
870 # APM
871   if checkbootparam 'noapm'; then
872     ewarn "Skipping APM Bios detection as requested on boot commandline." ; eend 0
873   else
874     modprobe apm power_off=1 >>$DEBUG 2>&1
875     if [ "$?" = "0" ] ; then
876        if [ -x /etc/init.d/apmd ] ;then
877           einfo "APM Bios found, enabling power management functions."
878           /etc/init.d/apmd start ; eend $?
879        fi
880     else
881       eerror "Loading apm module failed." ; eend 1
882     fi
883   fi
884 fi
885 }
886 # }}}
887
888 # {{{ PCMCIA Check/Setup
889 # This needs to be done before other modules are being loaded (by hwsetup)
890 config_pcmcia(){
891 if checkbootparam 'nopcmcia'; then
892   ewarn "Skipping PCMCIA detection as requested on boot commandline." ; eend 0
893 else
894   if /usr/sbin/laptop-detect ; then
895     einfo "Detected Laptop - checking for PCMCIA." && eend 0
896     modprobe pcmcia_core >>$DEBUG 2>&1
897     # Try Cardbus or normal PCMCIA socket drivers
898     modprobe yenta_socket >>$DEBUG 2>&1 || modprobe i82365 >>$DEBUG 2>&1 || modprobe pd6729 >>$DEBUG 2>&1 || modprobe tcic >>$DEBUG 2>&1
899     if [ "$?" = "0" ]; then
900       modprobe ds >>$DEBUG 2>&1
901       if [ -d /proc/bus/pccard ] ; then
902        if [ -x /sbin/cardmgr ] ; then
903         einfo "PCMCIA found, starting cardmgr."
904         cardmgr >>$DEBUG 2>&1 && sleep 6 && eend 0
905        else
906         eerror "No cardmgr found. Make sure package pcmciautils is installed, it should handle it instead." ; eend 1
907        fi
908       fi
909     fi
910   fi
911 fi
912 }
913 # }}}
914
915 # {{{ run software synthesizer via speakup
916 config_swspeak(){
917    if checkbootparam 'swspeak' ; then
918       einfo "Bootoption swspeak found."
919
920       if [ ! -d /proc/speakup/ ] && ! grep -q speakup_soft /proc/modules ; then
921          ewarn "Kernel does not support software speakup - trying to load kernel module:" ; eend 0
922          eindent
923          einfo "Loading speakup_soft"
924          if modprobe speakup_soft ; then
925             eend 0
926          else
927             flitewrapper "Fatal error setting up software speakup"
928             eend 1
929             return 1
930          fi
931          eoutdent
932       fi
933
934       if [ -d /proc/speakup/ ] || grep -q speakup_soft /proc/modules ; then
935          einfo "Kernel supports speakup." ; eend 0
936          eindent
937             einfo "Just run swspeak if you want to use software synthesizer via speakup."
938             flitewrapper "Finished activating software speakup. Just run swspeak when booting finished."
939          eoutdent
940       else
941          eerror "Kernel does not seem to support speakup. Skipping swspeak." ; eend 1
942          flitewrapper "Kernel does not seem to support speakup. Sorry."
943       fi
944    fi
945 }
946 # }}}
947
948 # {{{ support hardware synthesizer via speakup
949 config_hwspeak(){
950    if checkbootparam 'speakup.synth' ; then
951       einfo "Bootoption speakup.synth found."
952       eindent
953
954       module="$(getbootparam 'speakup.synth' 2>>$DEBUG)"
955       if [ -z "$module" ] ; then
956          eerror "Sorry, no speakup module specified for bootoption speakup.synth."
957          flitewrapper "Sorry, no speakup module specified for bootoption speakup.synth."
958       else
959          einfo "Trying to load $module"
960          modprobe "speakup_${module}"
961          eend $?
962       fi
963
964       if [ -d /proc/speakup/ ] || grep -q speakup /proc/modules ; then
965          einfo "Kernel should support speakup now." ; eend 0
966          flitewrapper "Kernel should support speakup now."
967       else
968          eerror "Kernel or hardware do not seem to support speakup. Skipping hwspeak." ; eend 1
969          flitewrapper "Kernel or hardware do not seem to support speakup. Sorry."
970       fi
971
972       eoutdent
973
974    # hwspeak:
975    elif checkbootparam 'hwspeak' ; then
976       einfo "Bootoption hwspeak found."
977
978       if [ ! -d /proc/speakup/ ] && ! grep -q speakup /proc/modules ; then
979          ewarn "Kernel does not support hardware speakup - trying to load kernel modules:" ; eend 0
980          eindent
981          if ! [ -d "/lib/modules/${KERNEL}/extra/speakup/" ] ; then
982             eerror "Kernel does not provide speakup modules, sorry." ; eend 1
983          else
984            for module in $(find "/lib/modules/${KERNEL}/extra/speakup/" -name \*.ko | \
985                            sed 's#.*speakup/##g ; s#.ko$##g' | \
986                            grep -ve speakup_soft -ve speakup_dummy | sort -u) ; do
987               einfo "Trying to load $module"
988               modprobe $module
989               eend $?
990            done
991          fi
992          eoutdent
993       fi
994
995       if [ -d /proc/speakup/ ] || grep -q speakup /proc/modules ; then
996          einfo "Kernel should support speakup now." ; eend 0
997          flitewrapper "Kernel should support speakup now."
998       else
999          eerror "Kernel or hardware do not seem to support speakup. Skipping hwspeak." ; eend 1
1000          flitewrapper "Kernel or hardware do not seem to support speakup. Sorry."
1001       fi
1002    fi
1003 }
1004 # }}}
1005
1006 # {{{ Check for blind option or brltty
1007 config_blind(){
1008 BLIND=""
1009 checkbootparam 'blind' && BLIND="yes"
1010 BRLTTY="$(getbootparam 'brltty' 2>>$DEBUG)"
1011
1012 if [ -n "$BLIND" -o -n "$BRLTTY" ]; then
1013   if [ -x /sbin/brltty ]; then
1014     # Blind option detected, start brltty now.
1015     # modprobe serial_core parport_serial generic_serial && echo "done"
1016     CMD=brltty
1017     BRLTYPE=""
1018     BRLDEV=""
1019     BRLTEXT=""
1020     if [ -n "$BRLTTY" ]; then
1021       # Extra options
1022       BRLTYPE="${BRLTTY%%,*}"
1023       R="${BRLTTY#*,}"
1024       if [ -n "$R" -a "$R" != "$BRLTTY" ]; then
1025         BRLTTY="$R"
1026         BRLDEV="${BRLTTY%%,*}"
1027         R="${BRLTTY#*,}"
1028         if [ -n "$R" -a "$R" != "$BRLTTY" ]; then
1029           BRLTTY="$R"
1030           BRLTEXT="${BRLTTY%%,*}"
1031           R="${BRLTTY#*,}"
1032         fi
1033       fi
1034     fi
1035     [ -n "$BRLTYPE" ] && CMD="$CMD -b $BRLTYPE"
1036     [ -n "$BRLDEV"  ] && CMD="$CMD -d $BRLDEV"
1037     [ -n "$BRLTEXT" ] && CMD="$CMD -t $BRLTEXT"
1038     einfo "Starting braille-display manager."
1039 #    ( exec $CMD & )
1040     ( sh -c "$CMD" & )
1041     sleep 2 && BLINDSOUND="yes"
1042     eend 0
1043   fi
1044 fi
1045 }
1046 # }}}
1047
1048 # {{{ Interactive configuration
1049 config_interactive(){
1050   ewarn "config_interactive is deprecated nowadays."
1051   ewarn "Please set CONFIG_INTERACTIVE='no' in /etc/grml/autoconfig" ; eend 0
1052 }
1053 # }}}
1054
1055 # {{{ AGP
1056 config_agp(){
1057 if checkbootparam 'forceagp' ; then
1058 # Probe for AGP. Hope this can fail safely
1059   grep -q "AGP" "/proc/pci" 2>>$DEBUG && { modprobe agpgart || modprobe agpgart agp_try_unsupported=1; } >>$DEBUG 2>&1 && einfo "AGP bridge detected." ; eend 0
1060 fi
1061 }
1062 # }}}
1063
1064 # {{{ automount(er)
1065 config_automounter(){
1066 if checkbootparam 'automounter' ; then
1067   RUNLEVEL="$(runlevel)"
1068   AUTOMOUNTER=""
1069   [ -x /etc/init.d/autofs ] && [ "$RUNLEVEL" != "N 1" ] && [ "$RUNLEVEL" != "N S" ] && AUTOMOUNTER="yes"
1070
1071 addautomount(){
1072 # /dev/ice  options
1073   d="${1##*/}"
1074   if [ -n "$AUTOMOUNTER" ]; then
1075     [ -d "/mnt/$d" -a ! -L "/mnt/$d" ] && rmdir /mnt/$d
1076     [ -d "/mnt/auto/$d" ] || mkdir -p "/mnt/auto/$d"
1077     [ -L "/mnt/$d" ]      || ln -s "/mnt/auto/$d" "/mnt/$d"
1078     anew="$d        -fstype=auto,$2 :$i"
1079     grep -q "$anew" "/etc/auto.mnt" || echo "$anew" >> /etc/auto.mnt
1080     AUTOMOUNTS="$AUTOMOUNTS $d"
1081     new="$1 /mnt/auto/$d  auto   users,noauto,exec,$2 0 0"
1082   else
1083     [ -d /mnt/$d ] && mkdir -p /mnt/$d
1084     new="$1 /mnt/$d  auto   users,noauto,exec,$2 0 0"
1085   fi
1086   grep -q "$new" "/etc/fstab" || echo "$new" >> /etc/fstab
1087 }
1088
1089   AUTOMOUNTS="floppy cdrom"
1090 # Add new devices to /etc/fstab and /etc/auto.mnt
1091   for i in /dev/cdrom?*; do
1092     if [ -L $i ]; then
1093       addautomount "$i" "ro"
1094     fi
1095   done
1096 fi
1097
1098 if [ -n "$AUTOMOUNTER" ]; then
1099 # Check for floppy dir, reinstall with automounter
1100   [ -d /mnt/floppy -a ! -L /mnt/floppy ] && rmdir /mnt/floppy
1101   [ -d /mnt/auto/floppy ] || mkdir -p /mnt/auto/floppy
1102   [ -L /mnt/floppy ] || ln -s /mnt/auto/floppy /mnt/floppy
1103   [ -d /mnt/cdrom -a ! -L /mnt/cdrom ] && rmdir /mnt/cdrom
1104   [ -d /mnt/auto/cdrom ] || mkdir -p /mnt/auto/cdrom
1105   [ -L /mnt/cdrom ] || ln -s /mnt/auto/cdrom /mnt/cdrom
1106   rm -f /etc/fstab.new
1107 # Replace paths from bootfloppy
1108   sed 's|/mnt/cdrom|/mnt/auto/cdrom|g;s|/mnt/floppy|/mnt/auto/floppy|g' /etc/fstab > /etc/fstab.new
1109   mv -f /etc/fstab.new /etc/fstab
1110 # Start automounter now
1111   einfo "Starting automounter for ${AUTOMOUNTS}."
1112   /etc/init.d/autofs start >>$DEBUG ; eend $?
1113 fi
1114 }
1115 # }}}
1116
1117 # {{{ Collect partitions from /proc/partitions first for enabling DMA
1118 check_partitions(){
1119 partitions=""
1120 IDEDISKS=""
1121 while read major minor blocks partition relax; do
1122   partition="${partition##*/}"
1123   [ -z "$partition" -o ! -e "/dev/$partition" ] && continue
1124   case "$partition" in
1125     hd?) IDEDISKS="$IDEDISKS $partition";;                # IDE  Harddisk, entire disk
1126     sd?) ;;                                               # SCSI Harddisk, entire disk
1127 #    [hs]d*) partitions="$partitions /dev/$partition";;    # IDE or SCSI disk partition
1128     [hs]d*|ub*) partitions="$partitions /dev/$partition";;    # IDE, USB or SCSI disk partition
1129   esac
1130 done <<EOT
1131 $(awk 'BEGIN{old="__start"}{if($0==old){exit}else{old=$0;if($4&&$4!="name"){print $0}}}' /proc/partitions)
1132 EOT
1133 }
1134 check_partitions >/dev/null 2>&1 # avoid output "check_partitions:3: read-only file system"
1135 # }}}
1136
1137 # {{{ Enable DMA for all IDE drives now if not disabled
1138 # Notice: Already done by linuxrc, but make sure it's done also on harddisk-installed systems
1139 config_dma(){
1140 if checkbootparam 'nodma'; then
1141   ewarn "Skipping DMA accelleration as requested on boot commandline." ; eend 0
1142 else
1143   for d in $(cd /proc/ide 2>>$DEBUG && echo hd[a-z]); do
1144     if test -d /proc/ide/$d; then
1145       if egrep -q 'using_dma[ \t]+0' /proc/ide/$d/settings 2>>$DEBUG; then
1146         MODEL="$(cat /proc/ide/$d/model 2>>$DEBUG)"
1147         test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]"
1148         einfo "Enabling DMA acceleration for: ${WHITE}$d        ${YELLOW}[${MODEL}]${NORMAL}"
1149         echo "using_dma:1" >/proc/ide/$d/settings
1150         eend 0
1151       fi
1152     fi
1153   done
1154 fi
1155 }
1156 # }}}
1157
1158 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
1159 config_fstab(){
1160
1161 NOSWAP="yes" # we do not use swap by default!
1162 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
1163    NOSWAP=''
1164    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
1165 fi
1166
1167 if checkbootparam 'nofstab' || checkbootparam 'forensic' ; then
1168   ewarn "Skipping /etc/fstab creation as requested on boot commandline." ; eend 0
1169 else
1170   einfo "Scanning for harddisk partitions and creating /etc/fstab. (Disable this via boot option: nofstab)"
1171   iszsh && setopt nonomatch
1172   if [ -x /usr/sbin/rebuildfstab ] ; then
1173      config_userfstab || fstabuser=grml
1174      /usr/sbin/rebuildfstab -r -u $fstabuser -g $fstabuser ; eend $?
1175   else
1176      ewarn "Command rebuildfstab not found. Install package grml-rebuildfstab." ; eend 1
1177   fi
1178 fi # checkbootparam nofstab/forensic
1179
1180 # Scan for swap, config, homedir - but only in live-mode
1181 if [ -z "$INSTALLED" ] ; then
1182    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
1183    GRML_IMG=""
1184    GRML_SWP=""
1185    HOMEDIR="$(getbootparam 'home')"
1186    if [ -n "$partitions" ]; then
1187       while read p m f relax; do
1188         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
1189         partoptions="users,exec"
1190         fnew=""
1191         # it's a swap partition?
1192         case "$f" in swap)
1193           eindent
1194           if [ -n "$NOSWAP" ]; then
1195              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
1196              eend 0
1197           else
1198              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
1199                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
1200                      if [ -n "$ANYSWAP" ] ; then
1201                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
1202                         swapon $p 2>>$DEBUG ; eend $?
1203                      else
1204                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
1205                      fi
1206                      ;;
1207                    *)
1208                      if [[ "$p" == LABEL* ]] ; then
1209                         p=$(blkid -t $p | awk -F: '{print $1}')
1210                      fi
1211                      if grep -q $p /proc/swaps ; then
1212                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
1213                      else
1214                         if [ -b "$p" ] ; then
1215                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
1216                         swapon $p 2>>$DEBUG ; eend $?
1217                         else
1218                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
1219                         fi
1220                      fi
1221                      ;;
1222              esac # dd-check
1223           fi # -n "$NOSWAP
1224           eoutdent
1225           continue
1226           ;;
1227         esac # it's a swap partition?
1228
1229         # mount read-only
1230         MOUNTOPTS="ro"
1231         case "$f" in
1232           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
1233           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
1234           *) continue ;;
1235           # *) NONEFOUND='1'; continue ;;
1236         esac
1237
1238         # use a swapfile
1239         if [ -z "$NOSWAP" ] ; then
1240            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
1241            # Activate swapfile, if exists
1242            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
1243         fi
1244         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
1245            mount -o remount,rw $m && MOUNTED=1
1246            if swapon "$SWAPFILE" 2>>$DEBUG ; then
1247               eindent
1248                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
1249               eoutdent
1250               fnew="$SWAPFILE swap swap defaults 0 0"
1251               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
1252               GRML_SWP="$GRML_SWP $SWAPFILE"
1253               eend 0
1254            fi
1255            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
1256         fi
1257
1258         # use a image as home
1259         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
1260         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
1261            if [ -n "$HOMEDIR" ]; then
1262               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
1263                  continue
1264               fi
1265            fi
1266            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
1267               GRML_IMG="$IMAGE"
1268               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
1269            fi
1270         fi
1271         eend 0
1272
1273         # Umount, if not in use
1274         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
1275
1276       done <<EOT
1277       $(cat /etc/fstab)
1278 EOT
1279    fi # -n $partitions
1280 fi # -z $INSTALLED
1281 }
1282 # }}}
1283
1284 # {{{ Mouse
1285 config_mouse(){
1286 if [ -n "$MOUSE_DEVICE" ] ; then
1287   einfo "Detecting mouse: ${MOUSE_FULLNAME} at ${MOUSE_DEVICE}" ; eend $?
1288 fi
1289 }
1290 # }}}
1291
1292 # {{{ IPv6 configuration
1293 # Load IPv6 kernel module and print IP adresses
1294 config_ipv6(){
1295 if checkbootparam 'ipv6'; then
1296   einfo "Enabling IPv6 as requested on boot commandline (sleeping for 2 seconds)"
1297   modprobe ipv6
1298   # we probably need some time until stateless autoconfiguration has happened
1299   sleep 2
1300   NETDEVICES="$(awk -F: '/eth.:|tr.:|wlan.:/{print $1}' /proc/net/dev 2>>$DEBUG)"
1301   for DEVICE in `echo "$NETDEVICES"`; do
1302     eindent
1303       einfo "$DEVICE:"
1304       ADDRESSES="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{print $3}')"
1305       COUNT="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{ sum += 1};END {print sum }')"
1306       eindent
1307         for ADDR in `echo "$ADDRESSES"` ; do
1308             einfo "$ADDR"
1309         done
1310         if [ "$COUNT" -eq "0" ] ; then
1311            einfo "(none)" ; eend 1
1312         fi
1313       eoutdent
1314     eoutdent
1315   done
1316   eend 0
1317 fi
1318 }
1319 # }}}
1320
1321 # {{{ Fat-Client-Version: DHCP Broadcast for IP address
1322 config_dhcp(){
1323 if checkbootparam 'nodhcp'; then
1324   ewarn "Skipping DHCP broadcast/network detection as requested on boot commandline." ; eend 0
1325 else
1326   NETDEVICES="$(awk -F: '/eth.:|tr.:|wlan.:/{print $1}' /proc/net/dev 2>>$DEBUG)"
1327   rm -rf /etc/network/status ; mkdir -p /etc/network/status
1328   for DEVICE in `echo "$NETDEVICES"` ; do
1329     einfo "Network device ${WHITE}${DEVICE}${NORMAL} detected, DHCP broadcasting for IP. (Backgrounding)"
1330     trap 2 3 11
1331     ifconfig $DEVICE up >>$DEBUG 2>&1
1332     ( pump -i $DEVICE --script=/usr/lib/grml-autoconfig/pump-runparts >>$DEBUG 2>&1 && echo finished_running_pump > /etc/network/status/$DEVICE ) &
1333     trap "" 2 3 11
1334     sleep 1
1335     eend 0
1336   done
1337   if [ -n "$INSTALLED" ] ; then
1338      ewarn 'If you want to disable automatic DHCP requests set CONFIG_DHCP=no in /etc/grml/autoconfig.'
1339      eend 0
1340   fi
1341 fi
1342 }
1343 # }}}
1344
1345 # {{{ CPU-detection
1346 config_cpu(){
1347 if checkbootparam 'nocpu'; then
1348   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
1349 else
1350   # check module dependencies
1351   cpufreq_check() {
1352    if ! [ -e /lib/modules/${KERNEL}/kernel/arch/x86/kernel/cpu/cpufreq ] ; then
1353       if [ -e /lib64 ] ; then
1354          [ -e /lib/modules/${KERNEL}/kernel/arch/x86_64/kernel/cpufreq ] || return 1
1355       else
1356          [ -e /lib/modules/${KERNEL}/kernel/arch/i386/kernel/cpu/cpufreq -o ! -e /lib/modules/${KERNEL}/kernel/drivers/cpufreq ] || return 1
1357       fi
1358    fi
1359   }
1360
1361   if [[ `grep -c processor /proc/cpuinfo` -gt 1 ]] ; then
1362      einfo "Detecting CPU:"
1363      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)
1364      echo $CPU | sed 's/ \{1,\}/ /g'
1365      eend 0
1366   else
1367      einfo "Detecting CPU: `awk -F: '/^processor/{printf " Processor"$2" is"};/^model name/{printf $2};/^vendor_id/{printf vendor};/^cpu MHz/{printf " %dMHz",int($2)};/^cache size/{printf ","$2" Cache"};/^$/{print ""}' /proc/cpuinfo 2>>$DEBUG` " ; eend 0
1368   fi
1369
1370   # Disclaimer: sorry for the tons of if/then/else... but this makes sure we use:
1371   # * it only if we have the according kernel modules available
1372   # * cpufreq not inside Virtual Box
1373   # * current version of /etc/init.d/loadcpufreq from Debian (to stay in sync)
1374   #   -> parse output of the initscript and output it according to our look'n'feel
1375   # * our own cpufreq-detect.sh if /etc/init.d/loadcpufreq isn't present
1376   if ! cpufreq_check ; then
1377     ewarn "Skipping cpufreq setup as module dependencies are not fulfilled." ; eend 1
1378   else
1379      # Virtual Box supports ACPI and laptop-detect would return with '0', so check for it:
1380      if [ -r /proc/acpi/battery/BAT0/info ] ; then
1381         if grep -q 'OEM info:                innotek' /proc/acpi/battery/BAT0/info ; then
1382            einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0
1383            return 0
1384         fi
1385      fi
1386      einfo "Trying to set up cpu frequency scaling:"
1387      eindent
1388      if [ -x /etc/init.d/loadcpufreq ] ; then
1389         SKIP_CPU_GOVERNOR=''
1390         LOADCPUFREQ=$(mktemp)
1391         /etc/init.d/loadcpufreq start >"$LOADCPUFREQ" 2>&1 ; RC=$?
1392         if grep -q FATAL "$LOADCPUFREQ" ; then
1393            eindent
1394              SKIP_CPU_GOVERNOR=1
1395              oldIFS="$IFS"
1396              IFS="
1397 "
1398               for line in $(grep FATAL "$LOADCPUFREQ" | sed 's/.*FATAL: //; s/ (.*)//') ; do
1399                   eerror "$line" ; eend $RC
1400               done
1401               IFS="$oldIFS"
1402            eoutdent
1403          elif grep -q done "$LOADCPUFREQ" ; then
1404            MODULE=$(grep done "$LOADCPUFREQ" | sed 's/.*done (\(.*\))./\1/')
1405            if [ -n "$MODULE" -a "$MODULE" != none ]; then
1406               einfo "Loading cpufreq kernel module $MODULE" ; eend 0
1407            else
1408               ewarn "Could not find an appropriate kernel module for cpu frequency scaling." ; eend 1
1409            fi
1410         fi
1411         rm -f $LOADCPUFREQ
1412      elif [ -r /usr/bin/cpufreq-detect.sh ] ; then
1413         . /usr/bin/cpufreq-detect.sh
1414         if [ -n "$MODULE" -a "$MODULE" != none ]; then
1415            einfo "Loading modules ${MODULE}"
1416            modprobe "$MODULE" >>$DEBUG || modprobe "$MODULE_FALLBACK" >>$DEBUG
1417            RC=$?
1418            if [[ "$RC" == 0 ]]; then
1419               eend 0
1420            else
1421               SKIP_CPU_GOVERNOR=1
1422               eend $RC
1423            fi
1424         else
1425            ewarn "Could not detect an appropriate CPU for use with cpu frequency scaling - skipping."
1426            eend 1
1427         fi # $MODULE
1428      fi # loadcpufreq
1429
1430      if [ -z "$SKIP_CPU_GOVERNOR" ] ; then
1431         einfo "Loading cpufreq_ondemand, setting ondemand governor"
1432         RC=0
1433         if modprobe cpufreq_ondemand ; RC=$? ; then
1434            for file in $(find /sys/devices/system/cpu/ -name scaling_governor 2>/dev/null) ; do
1435                echo ondemand > $file
1436            done
1437         fi
1438         eend $RC
1439      fi # cpu-governor
1440
1441      eoutdent
1442
1443   fi # cpufreq_check
1444 fi # checkbootparam nocpu
1445 }
1446 # }}}
1447
1448 # {{{ autostart of ssh
1449 config_ssh(){
1450 if checkbootparam 'ssh' ; then
1451    SSH_PASSWD=''
1452    SSH_PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
1453    einfo "Bootoption ssh found, trying to set password for user grml."
1454    eindent
1455    if [ -z "$SSH_PASSWD" ] ; then
1456       if [ -x /usr/bin/apg ] ; then
1457          SSH_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1458       elif [ -x /usr/bin/gpw ] ; then
1459          SSH_PASSWD="$(gpw 1)"
1460       elif [ -x /usr/bin/pwgen ] ; then
1461          SSH_PASSWD="$(pwgen -1 8)"
1462       elif [ -x /usr/bin/hexdump ] ; then
1463          SSH_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1464       elif [ -n "$RANDOM" ] ; then
1465          SSH_PASSWD="grml${RANDOM}"
1466       else
1467          SSH_PASSWD=''
1468          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1469          eend 1
1470       fi
1471
1472       if [ -n "$SSH_PASSWD" ] ; then
1473          ewarn "No given password for ssh found. Using random password: $SSH_PASSWD" ; eend 0
1474       fi
1475    fi
1476    eoutdent
1477
1478    # finally check if we have a password we can use:
1479    if [ -n "$SSH_PASSWD" ] ; then
1480       # chpasswd sucks, seriously.
1481       if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1482         echo "grml:$SSH_PASSWD" | chpasswd -m
1483       else
1484         echo "grml:$SSH_PASSWD" | chpasswd
1485       fi
1486    fi
1487
1488    einfo 'Starting secure shell server in background.'
1489    /etc/init.d/rmnologin start >>$DEBUG 2>>$DEBUG
1490    /etc/init.d/ssh start >>$DEBUG 2>>$DEBUG &
1491    eend $?
1492
1493    eindent
1494    ewarn 'Warning: please change the password for user grml as soon as possible!'
1495    eoutdent
1496 fi
1497 }
1498 # }}}
1499
1500 # {{{ autostart of x11vnc
1501 config_vnc(){
1502
1503 USER=grml # TODO: make it dynamically configurable
1504 if checkbootparam 'vnc' ; then
1505    VNC_PASSWD=''
1506    VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)"
1507    einfo "Bootoption vnc found, trying to set password for user $USER."
1508    eindent
1509    if [ -z "$VNC_PASSWD" ] ; then
1510       if [ -x /usr/bin/apg ] ; then
1511          VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1512       elif [ -x /usr/bin/gpw ] ; then
1513          VNC_PASSWD="$(gpw 1)"
1514       elif [ -x /usr/bin/pwgen ] ; then
1515          VNC_PASSWD="$(pwgen -1 8)"
1516       elif [ -x /usr/bin/hexdump ] ; then
1517          VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1518       elif [ -n "$RANDOM" ] ; then
1519          VNC_PASSWD="${USER}${RANDOM}"
1520       else
1521          VNC_PASSWD=''
1522          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1523          eend 1
1524       fi
1525
1526       if [ -n "$VNC_PASSWD" ] ; then
1527          ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0
1528       fi
1529    fi
1530    eoutdent
1531
1532    # finally check if we have a password we can use:
1533    if [ -n "$VNC_PASSWD" ] ; then
1534
1535       VNCDIR="/home/${USER}/.vnc"
1536       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1537
1538       if [ ! -x /usr/bin/x11vnc ] ; then
1539          eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package."
1540          eend 1
1541       else
1542          /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $?
1543          /bin/chown -R "$USER": "$VNCDIR"
1544       fi
1545    fi
1546 fi
1547 }
1548 # }}}
1549
1550 # {{{ set password for user grml
1551 config_passwd(){
1552 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1553   einfo "Bootoption passwd found."
1554   PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1555   if [ -n "$PASSWD" ] ; then
1556     echo "grml:$PASSWD" | chpasswd -m ; eend $?
1557   else
1558     eerror "No given password for ssh found. Autostart of SSH will not work." ; eend 1
1559   fi
1560   eindent
1561     ewarn "Warning: please change the password for user grml set via bootparameter as soon as possible!"
1562   eoutdent
1563 fi
1564 }
1565 # }}}
1566
1567 # {{{ Check for persistent homedir option and eventually mount /home from there, or use a loopback file.
1568 config_homedir(){
1569 if checkbootparam 'home' ; then
1570    ewarn "The \"home\" bootoption is deprecated, please use the persistency feature instead."; eend 1
1571 fi
1572 }
1573 # }}}
1574
1575 # {{{ Sound
1576
1577 config_mixer(){
1578 if ! [ -x /usr/bin/amixer ] ; then
1579   eerror "amixer binary not available. Can not set sound volumes therefore." ; eend 1
1580 else
1581
1582   if ! [ -r /proc/asound/cards ] ; then
1583      ewarn "No soundcard present, skipping mixer settings therefore." ; eend 0
1584      return
1585   fi
1586
1587   if checkbootparam 'vol' ; then
1588     VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1589     if [ -z "$VOL" ] ; then
1590       eerror "Bootoption vol found but no volume level/parameter given. Using defaults." ; eend 1
1591       VOL='75' # default
1592     fi
1593   else
1594     VOL='75' # default
1595   fi
1596
1597   if checkbootparam 'nosound' ; then
1598     einfo "Muting sound devices on request."
1599
1600     fix_ibm_sound 0
1601     # mute the master, this should be sufficient
1602     ERROR=$(amixer -q set Master mute)
1603     RC=$?
1604
1605     if [ -n "$ERROR" ] ; then
1606        eindent
1607        eerror "Problem muting sound devices: $ERROR"
1608        eoutdent
1609     fi
1610     eend $RC
1611   elif [ -z "$INSTALLED" ]; then
1612       einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1613
1614       fix_ibm_sound ${VOL}
1615
1616       # by default assume '0' as volume for microphone:
1617       if checkbootparam 'micvol' ; then
1618          MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1619       else
1620          MICVOL=0
1621       fi
1622
1623       # finally set the volumes:
1624       RC=0
1625       for CONTROL in Master PCM ; do
1626          amixer -q set ${CONTROL} ${VOL}%
1627          if [ $? -ne 0 ] ; then RC=$? ; fi
1628       done
1629       # dont know how to set microphone volume for all soundcards with amixer,
1630       # so use aumix instead :/
1631       if [ ${MICVOL} -ne 0 -a -x /usr/bin/aumix ] ; then
1632          aumix -m $MICVOL &>/dev/null
1633          if [ $? -ne 0 ] ; then RC=$? ; fi
1634       fi
1635
1636       eend $RC
1637   fi
1638
1639 fi
1640 }
1641
1642 # on some IBM notebooks the front control has to be toggled
1643 fix_ibm_sound() {
1644  if [ -z $1 ] ; then
1645     return
1646  fi
1647
1648  VOL=${1}
1649
1650  if [ -x /usr/bin/amixer ] ; then
1651     if amixer -q get Front >/dev/null 2>>$DEBUG ; then
1652        amixer -q set Front unmute &>/dev/null
1653        amixer -q set Front ${VOL}% &>/dev/null
1654     fi
1655  fi
1656 }
1657 # }}}
1658
1659 # {{{ modem detection
1660 config_modem(){
1661 if checkbootparam 'nomodem'; then
1662   ewarn "Skipping check for AC97 modem controller as requested on boot commandline." ; eend 0
1663 else
1664   if [ -x /etc/init.d/sl-modem-daemon ] ; then
1665      if lspci | grep Intel | grep -q "AC'97 Modem Controller" ; then
1666         einfo "AC97 modem controller detected. Start it running 'Start sl-modem-daemon'."
1667         eend 0
1668      fi
1669   fi
1670 fi
1671 }
1672 # }}}
1673
1674 # {{{ keyboard add-ons
1675 config_setkeycodes(){
1676 if checkbootparam 'setkeycodes' ; then
1677  einfo "Setting keycodes as requested via bootparameter 'setkeycodes'."
1678   # MS MM keyboard add-on
1679   # fix
1680   setkeycodes e001 126 &>/dev/null
1681   setkeycodes e059 127 &>/dev/null
1682   # fn keys
1683   setkeycodes e03b 59 &>/dev/null
1684   setkeycodes e008 60 &>/dev/null
1685   setkeycodes e007 61 &>/dev/null
1686   setkeycodes e03e 62 &>/dev/null
1687   setkeycodes e03f 63 &>/dev/null
1688   setkeycodes e040 64 &>/dev/null
1689   setkeycodes e041 65 &>/dev/null
1690   setkeycodes e042 66 &>/dev/null
1691   setkeycodes e043 67 &>/dev/null
1692   setkeycodes e023 68 &>/dev/null
1693   setkeycodes e057 87 &>/dev/null
1694   setkeycodes e058 88 &>/dev/null
1695   # hp keycodes
1696   setkeycodes e00a 89 e008 90 &>/dev/null
1697  eend 0
1698 fi
1699 }
1700 # }}}
1701
1702 # {{{ wondershaper
1703 config_wondershaper(){
1704  if checkbootparam 'wondershaper' ; then
1705     WONDER="$(getbootparam 'wondershaper' 2>>$DEBUG)"
1706     CMD=wondershaper
1707     DEVICE=""
1708     DOWNSTREAM=""
1709     UPSTREAM=""
1710     if [ -n "$WONDER" ]; then
1711       # Extra options
1712       DEVICE="${WONDER%%,*}"
1713       R="${WONDER#*,}"
1714       if [ -n "$R" -a "$R" != "$WONDER" ]; then
1715         WONDER="$R"
1716         DOWNSTREAM="${WONDER%%,*}"
1717         R="${WONDER#*,}"
1718         if [ -n "$R" -a "$R" != "$WONDER" ]; then
1719           WONDER="$R"
1720           UPSTREAM="${WONDER%%,*}"
1721           R="${WONDER#*,}"
1722         fi
1723       fi
1724     fi
1725     [ -n "$DEVICE" ]     && CMD="$CMD $DEVICE"
1726     [ -n "$DOWNSTREAM" ] && CMD="$CMD $DOWNSTREAM"
1727     [ -n "$UPSTREAM" ]   && CMD="$CMD $UPSTREAM"
1728     einfo "Starting wondershaper (${CMD}) in background."
1729     ( sh -c $CMD & ) && eend 0
1730  fi
1731 }
1732 # }}}
1733
1734 # {{{ syslog-ng
1735 config_syslog(){
1736  if checkbootparam 'nosyslog'; then
1737     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1738  else
1739     SYSLOGD=''
1740     [ -x /etc/init.d/syslog-ng ] && SYSLOGD='syslog-ng'
1741     [ -x /etc/init.d/rsyslog   ] && SYSLOGD='rsyslog'
1742     [ -x /etc/init.d/dsyslog   ] && SYSLOGD='dsyslog'
1743     [ -x /etc/init.d/sysklogd  ] && SYSLOGD='sysklogd'
1744     [ -x /etc/init.d/inetutils-syslogd ] && SYSLOGD='inetutils-syslogd'
1745
1746     if [ -z "$SYSLOGD" ] ; then
1747        eerror "No syslog daemon found." ; eend 1
1748     else
1749        einfo "Starting $SYSLOGD in background."
1750        /etc/init.d/$SYSLOGD start >>$DEBUG &
1751        eend 0
1752     fi
1753  fi
1754 }
1755 # }}}
1756
1757 # {{{ gpm
1758 config_gpm(){
1759  if checkbootparam 'nogpm'; then
1760   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1761  else
1762    if ! [ -r /dev/input/mice ] ; then
1763       eerror "No mouse found - not starting GPM." ; eend 1
1764    else
1765       einfo "Starting gpm in background."
1766       /etc/init.d/gpm start >>$DEBUG &
1767       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start >>$DEBUG ) &
1768       eend 0
1769    fi
1770  fi
1771 }
1772 # }}}
1773
1774 # {{{ services
1775 config_services(){
1776  if checkbootparam 'services' ; then
1777     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1778     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1779     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1780     einfo "Starting service(s) ${SERVICENL} in background."
1781     for service in $(echo -e $SERVICELIST) ; do
1782        /etc/init.d/${service} start >>$DEBUG &
1783     done
1784     [ "$?" == "0" ] ; eend $?
1785  fi
1786 }
1787 # }}}
1788
1789 # {{{ remote files
1790 get_remote_file() {
1791   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1792   SOURCE=$(eval echo "$1")
1793   TARGET="$2"
1794   getconfig() {
1795   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1796        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1797   }
1798   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1799   counter=10
1800   while ! getconfig && [[ "$counter" != 0 ]] ; do
1801     echo -n "Sleeping for 1 second and trying to get config again... "
1802     counter=$(( counter-1 ))
1803     echo "$counter tries left" ; sleep 1
1804   done
1805   if [ -s "$TARGET" ] ; then
1806     einfo "Downloading was successfull." ; eend 0
1807     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1808     md5sum ${TARGET} ; eend 0
1809     return 0;
1810   else
1811     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1812     return 1;
1813  fi
1814 }
1815 # }}}
1816
1817 # {{{ config files
1818 config_netconfig(){
1819  if checkbootparam 'netconfig' ; then
1820   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1821   CONFIGFILE='/tmp/netconfig.grml'
1822
1823   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1824     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1825   fi
1826
1827  fi
1828 }
1829 # }}}
1830
1831 # {{{ remote scripts
1832 config_netscript() {
1833  if checkbootparam 'netscript' ; then
1834   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1835   SCRIPTFILE='/tmp/netscript.grml'
1836
1837   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1838     chmod +x ${SCRIPTFILE}
1839     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && ${SCRIPTFILE} ; eend $?
1840   fi
1841
1842  fi
1843 }
1844 # }}}
1845
1846 # {{{ blindsound
1847 config_blindsound(){
1848  if checkbootparam 'blind' ; then
1849     beep
1850     flitewrapper "welcome to the gremel system"
1851  fi
1852 }
1853 # }}}
1854
1855 # {{{ welcome sound
1856 config_welcome(){
1857  if checkbootparam 'welcome' ; then
1858     flitewrapper "welcome to the gremel system"
1859  fi
1860 }
1861 # }}}
1862
1863 # {{{ fix/workaround for unionfs
1864 fix_unionfs(){
1865   if [ -z "$INSTALLED" ]; then
1866    touch /var/cache/apt/*cache.bin
1867   fi
1868 }
1869 # }}}
1870
1871 # {{{ create all /mnt-directories
1872 create_mnt_dirs(){
1873   ewarn "create_mnt_dirs is deprecated as grml-rebuildfstab does all we need."
1874   ewarn "Please set CONFIG_CREATE_MNT_DIRS='no' in /etc/grml/autoconfig" ; eend 0
1875 }
1876 # }}}
1877
1878 # {{{ start X window system via grml-x
1879 config_x_startup(){
1880 # make sure we start X only if startx is used *before* a nostartx option
1881 # so it's possible to disable automatic X startup using nostart
1882 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1883  if [ -x $(which X) ] ; then
1884   if [ -z "$INSTALLED" ] ; then
1885    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1886    if [ -z "$WINDOWMANAGER" ] ; then
1887      einfo "No window manager specified. Taking ${WHITE}wm-ng${NORMAL} as default." && eend 0
1888      WINDOWMANAGER="wm-ng"
1889    else
1890      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1891    fi
1892    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1893    config_userfstab || fstabuser='grml'
1894  cat>|/etc/init.d/xstartup<<EOF
1895 #!/bin/sh
1896 su $fstabuser -c "/usr/bin/grml-x $WINDOWMANAGER"
1897 EOF
1898    chmod 755 /etc/init.d/xstartup
1899
1900    # adjust inittab for xstartup
1901    if grep -q '^6:' /etc/inittab ; then
1902       sed -i 's|^6:.*|6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/bin/zsh-login" >/dev/tty6 2>\&1 </dev/tty6|' /etc/inittab
1903    else # just append tty6 to inittab if no definition is present:
1904       echo '6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/bin/zsh-login" >/dev/tty6 2>&1 < /dev/tty6' >> /etc/inittab
1905    fi
1906
1907    /sbin/telinit q ; eend $?
1908
1909    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1910       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1911    else
1912       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1913    fi
1914
1915   else
1916     eerror "We are not running in live mode - startx will not work, skipping it."
1917     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1918   fi
1919  else
1920    eerror "/usr/X11R6/bin/X is not present on this grml flavour."
1921    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1922  fi
1923 fi
1924 }
1925 # }}}
1926
1927 # {{{ configuration framework
1928 config_extract(){
1929 if checkbootparam 'extract' ; then
1930  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1931  EXTRACTOPTIONS="-- -x $EXTRACT"
1932 fi
1933 }
1934
1935 config_finddcsdir() {
1936 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1937 #    on the command line, nothing is changed and the dcs files are
1938 #    searched within the .iso, $dcs-dir is set to the root directory
1939 #    within the .iso
1940 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1941 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1942 #    set, $dcs-dir is set to the root directory within the .iso.
1943 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1944 #    foo, even if a GRMLCFG partition is present.
1945 DCSDIR=""
1946 DCSMP="/mnt/grml"
1947 if checkbootparam 'noautoconfig' || checkbootparam 'forensic' ; then
1948   ewarn "Skipping running automount of device(s) labeled GRMLCFG as requested." ; eend 0
1949 else
1950   if [ -z "$INSTALLED" ] ; then
1951     if checkbootparam 'myconfig' ; then
1952       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1953       if [ -z "$DCSDEVICE" ]; then
1954         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1955       fi # [ -z "$DCSDEVICE" ]
1956     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1957       einfo "Searching for device(s) labeled with GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1958       eindent
1959       # We do need the following fix so floppy disk is available to blkid in any case :-/
1960       if [ -r /dev/fd0 ] ; then
1961         einfo "Floppy device detected. Trying to access floppy disk."
1962         if timeout 4 dd if=/dev/fd0 of=/dev/null bs=512 count=1 >>$DEBUG 2>&1 ; then
1963            blkid /dev/fd0 >>$DEBUG 2>&1
1964         fi
1965       fi
1966       DCSDEVICE=$(blkid -t LABEL=GRMLCFG | head -1 | awk -F: '{print $1}')
1967       if [ -n "$DCSDEVICE" ]; then
1968         DCSMP="/mnt/grmlcfg"
1969       fi
1970       eoutdent
1971     fi
1972
1973     # if not specified/present then assume default:
1974     if [ -z "$DCSDEVICE" ]; then
1975       DCSDIR="/live/image"
1976     else
1977       eindent
1978       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1979       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1980       if [ -n "$DCSDIR" ]; then
1981         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1982       else
1983         [ -d $DCSMP ] || mkdir $DCSMP
1984         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1985         mount -o ro -t auto $DCSDEVICE  $DCSMP ; RC="$?"
1986         if [[ $RC == 0 ]]; then
1987           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1988         else
1989           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1990         fi
1991         DCSDIR="$DCSMP"
1992       fi
1993       eoutdent
1994     fi
1995   fi
1996 fi
1997
1998 if [ -n "$DCSDIR" -a "$DCSDIR" != "/live/image" ] ; then
1999   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
2000 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
2001   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
2002 fi
2003 }
2004
2005
2006 config_partconf() {
2007 if checkbootparam 'partconf' ; then
2008  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
2009  if [ -n "$MOUNTDEVICE" ]; then
2010    [ -d /mnt/grml ] || mkdir /mnt/grml
2011    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
2012     if [[ $RC == 0 ]]; then
2013       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
2014       einfo "Copying files from $MOUNTDEVICE over grml system."
2015       for file in `cat /etc/grml/partconf` ; do
2016         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
2017         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
2018       done && eend 0
2019     else
2020       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
2021     fi # mount $MOUNTDEVICE
2022    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
2023  else
2024    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
2025  fi # [ -n "$MOUNTDEVICE" ]
2026 fi
2027 }
2028 # }}}
2029
2030 # {{{ /cdrom/.*-options
2031 config_debs(){
2032 if checkbootparam 'debs' ; then
2033    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
2034    if ! echo $DEBS | grep -q '/'; then
2035      # backwards compatibility: if no path is given get debs from debs/
2036      DEBS="debs/$DEBS"
2037    fi
2038    einfo "Tring to install debian package(s) ${DEBS}"
2039    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
2040    dpkg -i $DEBS ; eend $?
2041 fi
2042 }
2043
2044 config_scripts(){
2045 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
2046    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
2047    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
2048      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
2049    fi
2050    if ! echo $SCRIPTS | grep -q '/'; then
2051      # backwards compatibility: if no path is given get scripts from scripts/
2052      SCRIPTS="scripts/$SCRIPTS"
2053    fi
2054    if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
2055      # we are executing from a GRMLCFG labeled fs
2056      # kick everything we have done before and start over
2057      SCRIPTS="$(cd ${DCSDIR}; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
2058    fi
2059    if [ -n "$SCRIPTS" ]; then
2060      SCRIPTS="${DCSDIR}/$SCRIPTS"
2061      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
2062        einfo "Trying to execute ${SCRIPTS}"
2063        sh -c $SCRIPTS
2064      elif [ -d "$SCRIPTS" ]; then
2065        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
2066        run-parts $SCRIPTS
2067      else
2068        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
2069        sh -c $SCRIPTS
2070      fi
2071    fi
2072 fi
2073 }
2074
2075 config_config(){
2076 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
2077   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
2078   if [ -z "$CONFIG" ]; then
2079     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
2080   fi
2081   if [ -n "$CONFIG" ]; then
2082     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
2083       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
2084
2085       cp -a ${DCSDIR}/${CONFIG}/* /
2086     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
2087       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
2088
2089       cd /
2090       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
2091     else
2092       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
2093     fi
2094   fi
2095 fi
2096 # umount $DCSMP if it was mounted by finddcsdir
2097 # this doesn't really belong here
2098 grep -q '$DCSMP' /proc/mounts && umount $DCSMP
2099 }
2100 # }}}
2101
2102 # {{{ mypath
2103 config_mypath(){
2104 if checkbootparam 'mypath' ; then
2105    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
2106    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
2107    touch /etc/grml/my_path
2108    chmod 644 /etc/grml/my_path
2109    # make sure the directories exist:
2110    eindent
2111    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
2112        if ! [ -d "$i" ] ; then
2113           einfo "Creating directory $i"
2114           mkdir -p "$i" ; eend $?
2115        fi
2116    done
2117    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
2118    eoutdent
2119 fi
2120 }
2121 # }}}
2122
2123 # {{{ distcc
2124 config_distcc(){
2125 if checkbootparam 'distcc' ; then
2126  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
2127  if [ -n "$OPTIONS" ]; then
2128     NET=""
2129     INTERFACE=""
2130     if [ -n "$OPTIONS" ]; then
2131       NET="${OPTIONS%%,*}"
2132       R="${OPTIONS#*,}"
2133       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2134         OPTIONS="$R"
2135         INTERFACE="${OPTIONS%%,*}"
2136         R="${OPTIONS#*,}"
2137       fi
2138     fi
2139  fi
2140  CONFIG=/etc/default/distcc
2141  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
2142  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
2143
2144  if [ -n "$INTERFACE" ] ; then
2145    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2146
2147    counter=10
2148    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
2149      counter=$(( counter-1 ))
2150      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
2151      sleep 3
2152      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
2153    done
2154  fi
2155
2156  if [ -n "$IP" ] ; then
2157    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
2158
2159    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
2160    eindent
2161     id distccd >/dev/null 2>&1 || \
2162     (
2163       einfo "Creating distcc user" ; \
2164       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
2165     )
2166
2167     einfo "Starting distcc for network ${NET}, listening on ${IP}."
2168    /etc/init.d/distcc start >/dev/null ; eend $?
2169    eoutdent
2170  else
2171    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
2172  fi
2173 fi
2174
2175 if checkbootparam 'gcc'; then
2176  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
2177  eindent
2178  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
2179  eoutdent
2180  rm -f /usr/bin/gcc
2181  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
2182 fi
2183
2184 if checkbootparam 'gpp'; then
2185  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
2186  eindent
2187   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
2188   if [ -x /usr/bin/g++-${GPP} ] ; then
2189      rm -f /usr/bin/g++
2190      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
2191   fi
2192   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
2193   if [ -x /usr/bin/cpp-${GPP} ] ; then
2194      rm -f /usr/bin/cpp
2195      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
2196   fi
2197  eoutdent
2198 fi
2199
2200 }
2201 # }}}
2202
2203 # {{{ load modules
2204 # Notice: use it only on live-cd system, if running from harddisk please
2205 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
2206 # in /etc/runlevel.conf
2207 config_modules(){
2208 MODULES_FILE=/etc/grml/modules
2209 if checkbootparam 'nomodules' ; then
2210   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
2211 elif [ -z "$INSTALLED" ]; then
2212  if [ -r $MODULES_FILE ] ; then
2213   einfo "Loading modules specified in ${MODULES_FILE}:"
2214   eindent
2215   grep '^[^#]' $MODULES_FILE | \
2216   while read module args; do
2217     [ "$module" ] || continue
2218       einfo "${module}"
2219       modprobe $module $args ; eend $?
2220   done
2221   eoutdent
2222  else
2223   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
2224  fi
2225 fi
2226 }
2227 # }}}
2228
2229 # {{{ 915resolution
2230 config_915resolution(){
2231 if checkbootparam '915resolution' ; then
2232  OPTIONS="$(getbootparam '915resolution' 2>>$DEBUG)"
2233   if [ -x /usr/sbin/915resolution ]; then
2234     CMD=915resolution
2235     MODE=""
2236     XRESO=""
2237     YRESO=""
2238     if [ -n "$OPTIONS" ]; then
2239       # Extra options
2240       MODE="${OPTIONS%%,*}"
2241       R="${OPTIONS#*,}"
2242       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2243         OPTIONS="$R"
2244         XRESO="${OPTIONS%%,*}"
2245         R="${OPTIONS#*,}"
2246         if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
2247           OPTIONS="$R"
2248           YRESO="${OPTIONS%%,*}"
2249           R="${OPTIONS#*,}"
2250         fi
2251       fi
2252     fi
2253     einfo "Running 915resolution with options ${MODE} ${XRESO} ${YRESO}."
2254     [ -n "$MODE" ] && [ -n "$XRESO"  ] && [ -n "$YRESO" ]  && ( sh -c "$CMD $MODE $XRESO $YRESO" & )
2255     eend 0
2256   fi
2257 fi
2258 }
2259 # }}}
2260
2261 # {{{ SW-RAID
2262 config_swraid(){
2263   [ -n "$INSTALLED" ] && return 0
2264
2265   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
2266   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
2267      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
2268      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
2269   else
2270     if ! [ -x /sbin/mdadm ] ; then
2271        eerror "mdadm not available, can not execute it." ; eend 1
2272     else
2273
2274        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2275        # find out whether we have a valid configuration file already
2276        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
2277           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
2278           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
2279           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
2280         else
2281           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
2282        fi
2283
2284        if ! checkbootparam 'swraid' ; then
2285           eindent
2286           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
2287           eoutdent
2288        else
2289           einfo "Bootoption swraid found. Searching for software RAID arrays:"
2290           eindent
2291            IFSOLD=${IFS:-}
2292            IFS='
2293 '
2294            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
2295                case $line in
2296                  *'No arrays found'*)
2297                    ewarn "$line" ; eend 0
2298                    ;;
2299                  *)
2300                    einfo "$line" ; eend 0
2301                    ;;
2302                esac
2303            done
2304            IFS=$IFSOLD
2305          eoutdent
2306
2307          if [ -r /proc/mdstat ] ; then
2308             eindent
2309             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
2310             if [ -z "$MDSTAT" ] ; then
2311                ewarn "No active arrays found" ; eend 0
2312             else
2313                IFSOLD=${IFS:-}
2314                IFS='
2315 '
2316                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
2317                    einfo "active arrays: $line" ; eend 0
2318                done
2319                IFS=$IFSOLD
2320             fi
2321             eoutdent
2322          fi # /proc/mdstat
2323        fi # bootoption swraid
2324
2325      fi # is /sbin/mdadm executable?
2326   fi # check for bootoptions
2327 }
2328 # }}}
2329
2330 # {{{ dmraid
2331 config_dmraid(){
2332   [ -n "$INSTALLED" ] && return 0
2333
2334   if checkbootparam 'nodmraid' ; then
2335     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
2336     return 0
2337   fi
2338
2339   if ! [ -x /sbin/dmraid ] ; then
2340     eerror "dmraid not available, can not execute it." ; eend 1
2341     return
2342   fi
2343
2344   dmraid_wrapper() {
2345     # usage: dmraid_wrapper <dmraid_option>
2346     [ -n "$1" ] || return 1
2347
2348     IFSOLD=${IFS:-}
2349     IFS='
2350 '
2351     eindent
2352
2353     for line in $(dmraid $1 ; echo errcode:$?); do
2354       case $line in
2355         *'no block devices found'*)
2356           einfo "No block devices found" ; eend 0
2357           break
2358           ;;
2359         *'no raid disks'*)
2360           einfo "No active dmraid devices found" ; eend 0
2361           break
2362           ;;
2363         errcode:0)
2364           eend 0;
2365           ;;
2366         errcode:1)
2367           eend 1
2368           ;;
2369         *)
2370           einfo "$line"
2371           ;;
2372       esac
2373     done
2374
2375     eoutdent
2376     IFS=$IFSOLD
2377   }
2378
2379   if checkbootparam 'dmraid' ; then
2380     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
2381     if [ "$ACTION" = "off" ] ; then
2382       # Deactivates all active software RAID sets:
2383       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
2384       dmraid_wrapper -an
2385     else
2386       # Activate all software RAID sets discovered:
2387       einfo "Activating present dmraid sets (as requested via dmraid):"
2388       dmraid_wrapper -ay
2389     fi
2390
2391     return
2392   fi
2393
2394   # by default (no special bootoptions) discover all software RAID devices:
2395   einfo "Searching for any present dmraid sets:"
2396   dmraid_wrapper -r
2397 }
2398 # }}}
2399
2400 # {{{ LVM (Logical Volumes)
2401 config_lvm(){
2402   [ -n "$INSTALLED" ] && return 0
2403
2404   if checkbootparam 'nolvm' ; then
2405      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
2406   else
2407     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
2408     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
2409        eerror "LVM not available, can not execute it." ; eend 1
2410     else
2411        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
2412           einfo "You seem to have logical volumes (LVM) on your system."
2413           eindent
2414           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
2415           eend 0
2416           if checkbootparam 'lvm' ; then
2417              einfo "Bootoption LVM found. Searching for logical volumes:"
2418              /etc/init.d/lvm2 start ; eend $?
2419           fi
2420           eoutdent
2421        fi
2422     fi # check for lvm binary
2423   fi # check for bootoption nolvm
2424 }
2425 # }}}
2426
2427 # {{{ debnet: setup network based on an existing one found on a partition
2428 config_debnet(){
2429 if checkbootparam 'debnet' ; then
2430  iszsh && setopt shwordsplit
2431  DEVICES="$(< /proc/partitions tail -n +3 | awk '{print "/dev/"$4}' | tr "\n" " ")"
2432  DEVICES="$DEVICES $(ls /dev/mapper/*)"
2433  FOUND_DEBNET=""
2434
2435  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
2436  eindent
2437  if ! mount | grep '/mnt ' >/dev/null 2>&1 ; then
2438     for i in $DEVICES; do
2439      if mount -o ro -t auto "$i" /mnt >/dev/null 2>&1; then
2440          einfo "Scanning on $i"
2441        if [ -f /mnt/etc/network/interfaces ]; then
2442          einfo "/etc/network/interfaces found on ${i}" ; eend 0
2443          FOUND_DEBNET="$i"
2444          break
2445        fi
2446        umount /mnt
2447      fi
2448     done
2449
2450    if [ -n "$FOUND_DEBNET" ]; then
2451      einfo "Stopping network."
2452        pump -k >/dev/null 2>&1
2453        /etc/init.d/networking stop >/dev/null 2>&1 ; eend $?
2454      einfo "Copying Debian network configuration from $FOUND_DEBNET to running system."
2455        rm -rf /etc/network/run
2456        cp -a /mnt/etc/network /etc
2457        rm -rf /etc/network/run
2458        mkdir /etc/network/run
2459        umount /mnt ; eend $?
2460      einfo "Starting network."
2461        invoke-rc.d networking start ; eend $?
2462    else
2463      eerror "/etc/network/interfaces not found." ; eend 1
2464    fi
2465    eoutdent
2466  else
2467   eerror "Error: /mnt already mounted." ; eend 1
2468  fi
2469 fi
2470 }
2471 # }}}
2472
2473 # {{{ check for broken ipw3945 driver which causes problems (especially on hd install)
2474 config_ipw3945() {
2475   if grep -q ipw3945 /proc/modules ; then
2476      if ! iwconfig 2>/dev/null| grep -qe 'IEEE 802' -qe 'unassociated' ; then
2477         ewarn "Broken ipw3945 network interface found, reloading module."
2478         rmmod ipw3945
2479         modprobe ipw3945
2480         eend $?
2481      fi
2482   fi
2483 }
2484 # }}}
2485
2486 # {{{ disable console blanking
2487 config_blanking(){
2488 if checkbootparam 'noblank' ; then
2489   einfo "Bootoption noblank found. Disabling monitor blanking."
2490   setterm -blank 0 ; eend $?
2491 fi
2492 }
2493 # }}}
2494
2495 # {{{ tohd= bootoption
2496 config_tohd()
2497 {
2498   if checkbootparam 'tohd' ; then
2499      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
2500      if [ -z "$TARGET" ] ; then
2501         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
2502         eerror "Please use something like tohd=/dev/sda9." ; eend 1
2503         return 1
2504      fi
2505
2506      if ! [ -b "$TARGET" ] ; then
2507         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
2508         return 1
2509      fi
2510
2511      if grep -q $TARGET /proc/mounts ; then
2512         eerror "$TARGET already mounted, skipping execution of tohd therefore."
2513         eend 1
2514         return 1
2515      fi
2516
2517      local MOUNTDIR=$(mktemp -d)
2518
2519      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
2520         einfo "Copyring live system to $TARGET - this might take a while"
2521         rsync -a --progress /live/image/live $MOUNTDIR
2522         sync
2523         umount "$MOUNTDIR"
2524         eend $?
2525         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
2526      else
2527         eerror "Error when trying to mount $TARGET, sorry."; eend 1
2528         return 1
2529      fi
2530
2531      rmdir "$MOUNTDIR"
2532   fi
2533 }
2534 # }}}
2535
2536 # {{{ grml2hd: automatic installation
2537 config_grml2hd(){
2538
2539 if checkbootparam "BOOT_IMAGE=grml2hd" ; then
2540
2541 if checkbootparam 'user' ; then
2542    NEWUSER=''
2543    NEWUSER="$(getbootparam 'user' 2>>$DEBUG)"
2544    sed -i "s/^NEWUSER=.*/NEWUSER=$NEWUSER/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2545 fi
2546
2547 if checkbootparam 'filesystem' ; then
2548    FILESYSTEM=''
2549    FILESYSTEM="$(getbootparam 'filesystem' 2>>$DEBUG)"
2550    sed -i "s/^FILESYSTEM=.*/FILESYSTEM=$FILESYSTEM/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2551 fi
2552
2553 if checkbootparam 'partition' ; then
2554    PARTITION=''
2555    PARTITION="$(getbootparam 'partition' 2>>$DEBUG)"
2556    # notice: the following checks whether the given partition is available, if not the skip
2557    # execution of grml2hd as it might result in data loss...
2558    if [ -r $PARTITION ] ; then
2559       sed -i "s#^PARTITION=.*#PARTITION=$PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2560    else
2561       ewarn "Partition $PARTITION does not exist. Skipping execution of grml2hd therefore." ; eend 1
2562    fi
2563 fi
2564
2565 if checkbootparam 'mbr' ; then
2566    BOOT_PARTITION=''
2567    BOOT_PARTITION="$(getbootparam 'mbr' 2>>$DEBUG)"
2568    sed -i "s#^BOOT_PARTITION=.*#BOOT_PARTITION=$BOOT_PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2569 fi
2570
2571 cat>|/usr/bin/grml2hd_noninteractive<<EOF
2572 #!/bin/sh
2573 GRML2HD_NONINTERACTIVE='yes' grml2hd
2574 EOF
2575
2576 chmod 755 /usr/bin/grml2hd_noninteractive
2577 einfo "Bootoption grml2hd found. Running automatic installation via grml2hd using /etc/grml2hd/config." && eend 0
2578 if [ -z "$GRML2HD_FAIL" ] ; then
2579    screen /usr/bin/grml2hd_noninteractive ; einfo "Invoking a shell, just exit to continue booting..." ; /bin/zsh
2580 else
2581    ewarn "There was an error adjusting /etc/grml2hd/config. Skipping execution of grml2hd for security reasons." ; eend 1
2582 fi
2583
2584 fi # if checkbootparam "BOOT_IMAGE=grml2hd ...
2585 }
2586 # }}}
2587
2588 # {{{ debootstrap: automatic installation
2589 config_debootstrap(){
2590
2591 if checkbootparam "BOOT_IMAGE=debian2hd" ; then
2592
2593 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
2594
2595 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
2596    eindent
2597    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
2598    eoutdent
2599    exit 1
2600 fi
2601
2602 if checkbootparam 'target' ; then
2603   TARGET=''
2604   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
2605   # notice: the following checks whether the given partition is available, if not the skip
2606   # execution of grml-debootstrap as it might result in data loss...
2607   if ! [ -r "$TARGET" ] ; then
2608      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
2609   fi
2610 else
2611   eindent
2612   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
2613   eoutdent
2614   exit 1
2615 fi
2616
2617 if checkbootparam 'grub' ; then
2618   GRUB=''
2619   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2620 fi
2621
2622 if checkbootparam 'groot' ; then
2623   GROOT=''
2624   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2625 fi
2626
2627 if checkbootparam 'release' ; then
2628   RELEASE=''
2629   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2630 fi
2631
2632 if checkbootparam 'mirror' ; then
2633   MIRROR=''
2634   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2635 fi
2636
2637 if checkbootparam 'boot_append' ; then
2638   BOOT_APPEND=''
2639   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2640 fi
2641
2642 if checkbootparam 'password' ; then
2643   PASSWORD=''
2644   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2645 fi
2646
2647 # now check which options are available
2648 if [ -n "TARGET" ] ; then
2649    TARGETCMD="--target $TARGET"
2650 else
2651    TARGETCMD=''
2652    eindent
2653    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2654    eoutdent
2655    exit 1
2656 fi
2657 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2658 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2659 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2660 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2661 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2662 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2663
2664 # and finally write script and execute it
2665 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2666 #!/bin/sh
2667 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2668 EOF
2669
2670 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2671
2672 screen /usr/bin/grml-debootstrap_noninteractive
2673 einfo "Invoking a shell, just exit to continue booting..."
2674 /bin/zsh
2675
2676 fi # checkbootparam "BOOT_IMAGE=debian2hd
2677 }
2678 # }}}
2679
2680 # {{{ Support customization
2681 config_distri(){
2682 if checkbootparam 'distri'; then
2683   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2684   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2685      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2686      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2687      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2688      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2689   fi
2690 fi
2691 }
2692 # }}}
2693
2694 ### {{{ backwards compatible stuff
2695 config_environment(){
2696   ewarn "config_environment is deprecated. Please set CONFIG_ENVIRONMENT in /etc/grml/autoconfig to 'no'." ; eend 0
2697 }
2698 config_keyboard(){
2699   ewarn "config_keyboard is deprecated. Please set CONFIG_KEYBOARD in /etc/grml/autoconfig to 'no'." ; eend 0
2700 }
2701 # }}}
2702
2703 ## END OF FILE #################################################################
2704 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3