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