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