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