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