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