a9c50438c316fdfd525c997f062e31ca141edb5b
[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 ### }}}
102
103 # {{{ filesystems (proc, pts, sys) and fixes
104 mount_proc(){
105   [ -f /proc/version ] || mount -t proc /proc /proc 2>/dev/null
106 }
107
108 mount_pts(){
109   grep -q "/dev/pts" /proc/mounts || mount -t devpts /dev/pts /dev/pts 2>/dev/null
110 }
111
112 mount_sys(){
113   [ -d /sys/devices ] || mount -t sysfs /sys /sys 2>/dev/null
114 }
115 # }}}
116
117 # {{{ Check if we are running in live mode or from HD
118 INSTALLED=""
119 [ -e /etc/grml_cd ] || INSTALLED="yes"
120
121 # testcd
122 TESTCD=""
123 checkbootparam 'testcd' >>$DEBUG 2>&1 && TESTCD="yes"
124 # }}}
125
126 # {{{ source lsb-functions , color handling
127 if checkbootparam 'nocolor'; then
128   RC_NOCOLOR=yes
129   . /etc/grml/lsb-functions
130   einfo "Disabling colors in bootsequence as requested on commandline." ; eend 0
131 else
132   . /etc/grml/lsb-functions
133   . /etc/grml_colors
134 fi
135 # }}}
136
137 # {{{ debug
138 config_debug(){
139  checkbootparam 'debug'            && BOOTDEBUG="yes"
140  checkbootparam "BOOT_IMAGE=debug" && BOOTDEBUG="yes"
141
142  rundebugshell(){
143   if [ -n "$BOOTDEBUG" ]; then
144      einfo "Starting intermediate shell stage $stage as requested by \"debug\" option."
145      if [ grep -q "debug=noscreen" "$CMDLINE" ] ; then
146         einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
147         einfo "Just exit the shell to continue boot process..."
148         /bin/zsh
149      else
150         eindent
151         if [ -r /etc/grml/screenrc ] ; then
152            einfo "Starting GNU screen to be able to use a full featured shell environment."
153            einfo "Just exit the shells (and therefore screen) to continue boot process..."
154            /bin/zsh -c "screen -c /etc/grml/screenrc"
155         else
156            einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
157            einfo "Just exit the shell to continue boot process..."
158            /bin/zsh
159         fi
160         eoutdent
161      fi
162   fi
163  }
164 }
165 # }}}
166
167 # {{{ log
168 config_log(){
169 if checkbootparam 'log' || checkbootparam 'debug' ; then
170    export DEBUG="/tmp/grml.log.`date +%Y%m%d`"
171    touch $DEBUG
172    einfo "Bootparameter log found. Log files: ${DEBUG} and /var/log/boot"
173    eindent
174      einfo "Starting bootlogd." # known to be *very* unreliable :(
175      bootlogd -r -c >>$DEBUG 2>&1 ; eend $?
176    eoutdent
177 else
178    DEBUG="/dev/null"
179 fi
180 }
181 # }}}
182
183 # {{{ set firmware timeout via bootparam
184 config_fwtimeout(){
185  if checkbootparam 'fwtimeout' ; then
186    TIMEOUT="$(getbootparam 'fwtimeout' 2>>$DEBUG)"
187    einfo "Bootoption fwtimeout found. (Re)Loading firmware_class module."
188    rmmod firmware_class >>$DEBUG 2>&1
189    modprobe firmware_class ; eend $?
190  fi
191  if [ -z "$TIMEOUT" ] ; then
192    TIMEOUT="100" # linux kernel default: 10
193  fi
194  if [ -f /sys/class/firmware/timeout ] ; then
195    einfo "Setting timeout for firmware loading to ${TIMEOUT}."
196    echo 100 > /sys/class/firmware/timeout ; eend $?
197  fi
198 }
199 # }}}
200
201 ### {{{ language configuration / localization
202 config_language(){
203
204  einfo "Activating language settings:"
205  eindent
206
207  # people can specify $LANGUAGE and $CONSOLEFONT in a config file
208  [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
209
210  # check for bootoption which overrides config from /etc/grml/autoconfig
211  BOOT_LANGUAGE="$(getbootparam 'lang' 2>>$DEBUG)"
212  [ -n "$BOOT_LANGUAGE" ] && LANGUAGE="$BOOT_LANGUAGE"
213
214  # set default to 'en' in live-cd mode iff $LANGUAGE is not set yet
215  if [ -z "$INSTALLED" ] ; then
216     [ -n "$LANGUAGE" ] || LANGUAGE='en'
217  fi
218
219  if [ -x /usr/sbin/grml-setlang ] ; then
220    # if bootoption lang is used update /etc/default/locale accordingly
221    if [ -n "$BOOT_LANGUAGE" ] ; then
222      checkgrmlsmall && /usr/sbin/grml-setlang "POSIX" || /usr/sbin/grml-setlang "$LANGUAGE"
223    # otherwise default to lang=en
224    else
225      checkgrmlsmall && /usr/sbin/grml-setlang "POSIX" || /usr/sbin/grml-setlang "en"
226    fi
227  fi
228
229  # set console font
230  if [ -z "$CONSOLEFONT" ] ; then
231     if ! checkbootparam 'nodefaultfont' >>$DEBUG 2>&1 ; then
232        if [ -r /usr/share/consolefonts/Uni3-Terminus16.psf.gz ] ; then
233           CONSOLEFONT='Uni3-Terminus16'
234        else
235           ewarn "/usr/share/consolefonts/Uni3-Terminus16.psf.gz not available. Please upgrade package console-terminus." ; eend 1
236        fi
237        if ! hasfb ; then
238           CONSOLEFONT='Lat15-Terminus16'
239        fi
240     fi
241  fi
242
243  # export it now, so error messages get translated, too
244  if checkgrmlsmall ; then
245     export LANG='C' # grml-small does not provide any further locales
246  else
247     [ -r /etc/default/locale ] && . /etc/default/locale
248     export LANG LANGUAGE
249  fi
250
251  # configure keyboard layout, read in already set values first:
252  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
253
254  # now allow keyboard override by boot commandline for later use:
255  KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
256  [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
257  # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
258  [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
259  [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
260
261  # modify /etc/sysconfig/keyboard only in live-cd mode:
262  if [ -z "$INSTALLED" ] ; then
263
264    local LANGUAGE="$BOOT_LANGUAGE"
265    . /etc/grml/language-functions
266    # allow setting xkeyboard explicitly different than console keyboard
267    KXKEYBOARD="$(getbootparam 'xkeyboard' 2>>$DEBUG)"
268    if [ -n "$KXKEYBOARD" ]; then
269       XKEYBOARD="$KXKEYBOARD"
270       KDEKEYBOARD="$KXKEYBOARD"
271    elif [ -n "$KKEYBOARD" ]; then
272       XKEYBOARD="$KKEYBOARD"
273       KDEKEYBOARD="$KKEYBOARD"
274    fi
275
276    # duplicate of previous code to make sure /etc/grml/language-functions
277    # does not overwrite our values....
278    # now allow keyboard override by boot commandline for later use:
279    KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
280    [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
281    # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
282    [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
283    [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
284
285    # write keyboard related variables to file for later use
286    [ -d /etc/sysconfig ] || mkdir /etc/sysconfig
287    if ! [ -e /etc/sysconfig/keyboard ] ; then
288       echo "KEYTABLE=\"$KEYTABLE\""          > /etc/sysconfig/keyboard
289       echo "XKEYBOARD=\"$XKEYBOARD\""       >> /etc/sysconfig/keyboard
290       echo "KDEKEYBOARD=\"$KDEKEYBOARD\""   >> /etc/sysconfig/keyboard
291       echo "KDEKEYBOARDS=\"$KDEKEYBOARDS\"" >> /etc/sysconfig/keyboard
292    fi
293  fi
294
295  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
296
297  # activate unicode console if running within utf8 environment
298  if [ -r /etc/default/locale ] ; then
299     if grep -q "LANG=.*UTF" /etc/default/locale ; then
300        einfo "Setting up unicode environment."
301        unicode_start >>$DEBUG 2>&1 ; eend $?
302     fi
303  fi
304
305  # Set default keyboard before interactive setup
306  if [ -n "$KEYTABLE" ] ; then
307     einfo "Running loadkeys for ${WHITE}${KEYTABLE}${NORMAL} in background"
308     loadkeys -q $KEYTABLE &
309     eend $?
310  fi
311
312  # we have to set up all consoles, therefore loop it over all ttys:
313  NUM_CONSOLES=$(fgconsole --next-available 2>/dev/null)
314  if [ -n "$NUM_CONSOLES" ] ; then
315     NUM_CONSOLES=$(expr ${NUM_CONSOLES} - 1)
316     [ ${NUM_CONSOLES} -eq 1 ] && NUM_CONSOLES=6
317  fi
318  CUR_CONSOLE=$(fgconsole 2>/dev/null)
319
320  if [ -x "$(which setfont)" ] ; then
321     use_setfont=true
322  elif [ -x "$(which consolechars)" ] ; then
323     use_consolechars=true
324  else
325     eerror "Neither setfont nor consolechars tool present, can not set font."
326     eend 1
327     return 1
328  fi
329
330  if [ -n "$CHARMAP" ] ; then
331     einfo "Setting font to ${CHARMAP}"
332     RC=0
333     for vc in $(seq 0 ${NUM_CONSOLES}) ; do
334         if $use_setfont ; then
335           setfont -C /dev/tty${vc} $CHARMAP ; RC=$?
336         elif $use_consolechars ; then
337           consolechars --tty=/dev/tty${vc} -m ${CHARMAP} ; RC=$?
338         fi
339     done
340     if [ -n "$CUR_CONSOLE" ] ; then
341        [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
342     fi
343     eend $RC
344  fi
345
346  if checkbootparam 'noconsolefont' ; then
347     ewarn "Skipping setting console font as requested on boot commandline." ; eend 0
348  else
349     if [ -n "$CONSOLEFONT" ] ; then
350        einfo "Setting font to ${CONSOLEFONT}"
351        RC=0
352        for vc in $(seq 0 ${NUM_CONSOLES}) ; do
353            if $use_setfont ; then
354              setfont -C /dev/tty${vc} ${CONSOLEFONT} ; RC=$?
355            elif $use_consolechars ; then
356              consolechars --tty=/dev/tty${vc} -f ${CONSOLEFONT} ; RC=$?
357            fi
358        done
359        if [ -n "$CUR_CONSOLE" ] ; then
360           [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
361        fi
362        eend $RC
363     fi
364  fi
365
366  eoutdent
367 }
368 # }}}
369
370 # {{{ Set hostname
371 config_hostname(){
372  if checkbootparam 'hostname' ; then
373   HOSTNAME="$(getbootparam 'hostname' 2>>$DEBUG)"
374   if [ -z "$HOSTNAME" ] && [ -x /usr/bin/random-hostname ] ; then
375      einfo "Generating random hostname as no hostname was specified."
376      HOSTNAME="$(/usr/bin/random-hostname)"
377      eend $?
378   fi
379   einfo "Setting hostname to $HOSTNAME as requested."
380   grml-hostname $HOSTNAME >>$DEBUG ; RC=$?
381   [ "$RC" = "0" ] && hostname $HOSTNAME
382   eend $RC
383  else
384   hostname --file /etc/hostname
385  fi
386 }
387 # }}}
388
389 # fstabuser (needed when running from harddisk with username != grml {{{
390 config_userfstab(){
391   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
392   if [ -n "$CONFIG_FSTAB_USER" ] ; then
393      fstabuser="$CONFIG_FSTAB_USER"
394   else
395      fstabuser=$(getent passwd 1000 | cut -d: -f1)
396   fi
397   # if not yet set fall back to default 'grml' user
398   [ -n "$fstabuser" ] || fstabuser='grml'
399 }
400 # }}}
401
402 # {{{ Set clock (Local time is more often used than GMT, so it is default)
403 config_time(){
404  # don't touch the files if running from harddisk:
405  if [ -z "$INSTALLED" ]; then
406     # The default hardware clock timezone is stated as representing local time.
407     UTC="--localtime"
408     grep -q "^UTC=" /etc/default/rcS || echo "UTC=no" >> /etc/default/rcS
409     checkbootparam 'utc'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
410     checkbootparam 'gmt'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
411     checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=no|"  /etc/default/rcS
412     grep -q -i "^UTC=yes" /etc/default/rcS && UTC="-u"
413     # hwclock uses the TZ variable
414     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
415     [ -z "$KTZ" ] && [ -r /etc/timezone ] && KTZ=$(cat /etc/timezone)
416     if [ ! -f "/usr/share/zoneinfo/$KTZ" ] ; then
417        ewarn "Warning: unknown timezone $KTZ" ; eend 1
418        KTZ="Europe/Vienna"
419        ewarn "Falling back to timezone $KTZ" ; eend 0
420     fi
421
422     if ! [ -r /dev/rtc ] ; then
423       ewarn "Warning: realtime clock not available, trying to execute hwclock anyway." ; eend 0
424     fi
425
426     ERROR=$(TZ="$KTZ" hwclock $UTC -s 2>&1 | head -1) ; RC=$?
427     if [ -n "$ERROR" ] ; then
428        eindent
429        ERROR=$(TZ="$KTZ" hwclock $UTC -s --directisa 2>&1 | head -1)
430        if [ -n "$ERROR" ] ; then
431           eerror "Problem running hwclock: $ERROR" ; eend 1
432        fi
433        eoutdent
434     fi
435
436  fi
437 }
438 # }}}
439
440 # {{{ print kernel info
441 config_kernel(){
442   vmware-detect &>/dev/null && VMWARE="inside ${WHITE}VMware/Qemu${NORMAL}"
443   [ -d /proc/xen ] && VMWARE='' # vmware-detect returns '0' when running with a Xen-enabled kernel
444   einfo "Running Linux Kernel $KERNEL $VMWARE" ; eend 0
445   if [ -r /proc/cpuinfo ] ; then
446      if egrep -q '^flags.*(vmx|svm)' /proc/cpuinfo ; then
447        eindent
448        einfo 'CPU(s) featuring virtualization technology detected' ; eend 0
449        eoutdent
450      fi
451   fi
452   if [ -d /proc/xen ] ; then
453      eindent
454      einfo 'Running kernel featuring support for Xen detected' ; eend 0
455      eoutdent
456   fi
457 }
458 # }}}
459
460 # {{{ ld.so.cache + depmod
461 config_ld_mod(){
462 if [ -n "$INSTALLED" ]; then
463  if ! [ -r /etc/grml.first.boot ] ; then
464   einfo "Running from HD for the first time, regenerate ld.so.cache and modules.dep:"
465   eindent
466 # Regenerate ld.so.cache and module dependencies on HD
467     einfo "Running ldconfig" ; ldconfig  ; eend $?
468     einfo "Running depmod"   ; depmod -a ; eend $?
469     touch /etc/grml.first.boot
470     eend 0
471   eoutdent
472  fi
473 fi
474 }
475 # }}}
476
477 # {{{ timezone
478 config_timezone(){
479  # don't touch the files if running from harddisk:
480  if [ -z "$INSTALLED" ]; then
481     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
482     if [ -n "$KTZ" ] ; then
483        if [ ! -f "/usr/share/zoneinfo/$KTZ" ]
484        then
485           ewarn "Warning: unknown timezone $KTZ"; eend 0
486        else
487           einfo "Setting timezone."
488           # update debconf
489           area=$(echo $KTZ | cut -d '/' -f1)
490           zone=$(echo $KTZ | cut -d '/' -f2)
491           echo "tzdata tzdata/Areas       select $area" | debconf-set-selections
492           echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections
493           # update files
494           echo $KTZ > /etc/timezone
495           rm -f /etc/localtime
496           cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $?
497        fi
498     fi
499  fi
500 }
501 # }}}
502
503 # small computer / nearly no ram {{{
504 config_small(){
505
506 RAM=$(/usr/bin/gawk '/MemTotal/{print $2}' /proc/meminfo)
507 # MEM=$(/usr/bin/gawk 'BEGIN{m=0};/MemFree|Cached|SwapFree/{m+=$2};END{print m}' /proc/meminfo)
508 eindent
509
510 if checkbootparam 'small'; then
511   einfo "Information: ${RAM} kB of RAM available." ; eend 0
512   einfo "Bootoption small detected. Activating small system."
513   if [ -r /etc/inittab.small ] ; then
514     mv /etc/inittab /etc/inittab.normal
515     mv /etc/inittab.small /etc/inittab
516   else
517     sed -i 's/^9/#&/' /etc/inittab
518     sed -i 's/^10/#&/' /etc/inittab
519     sed -i 's/^11/#&/' /etc/inittab
520     sed -i 's/^12/#&/' /etc/inittab
521   fi
522   /sbin/telinit q ; eend $?
523 else
524   if checkgrmlsmall ; then
525     if [[ $RAM -lt 25000 ]] ; then
526       ewarn "Information: ${RAM} kB of RAM available." ; eend 1
527       ewarn "At least 32MB of RAM should be available for grml-small." ; eend 1
528       ewarn "Use the bootoption small to save some more MB of memory usage." ; eend 0
529       ewarn "Dropping you into a rescue shell. To continue booting exit the shell." ; eend 0
530       /bin/zsh --login
531     else
532       einfo "Information: ${RAM} kB of RAM available." ; eend 0
533     fi
534   else
535     if [[ $RAM -lt 58000 ]] ; then
536       ewarn "Information: ${RAM} kB of RAM available." ; eend 1
537       ewarn "At least 64MB of RAM should be available for grml." ; 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   fi
545 fi
546 eoutdent
547 }
548 # }}}
549
550 # skip startup of w3m {{{
551 config_fast(){
552 if checkbootparam 'fast'; then
553   ewarn "Bootoption fast detected. Skipping startup of grml-quickconfig."
554     sed -i 's#^1:.*#1:12345:respawn:/usr/bin/openvt -f -c 1 -w -- /bin/zsh#' /etc/inittab
555   /sbin/telinit q ; eend $?
556 fi
557 }
558 # }}}
559
560 # activate serial console {{{
561 config_console(){
562 if checkbootparam 'console'; then
563   local line
564   local ws
565   ws='   '
566
567   einfo "Bootoption for serial console detected:"
568
569   line="$CMDLINE x "
570   this=""
571   line="${line#*[$ws]}"
572   local telinitq=""
573   while [ -n "$line" ]; do
574     case "$this" in
575       console=*)
576         local serial="$this"
577         local device="${this%%,*}"
578         local device="${device##*=}"
579         if echo $serial | grep -q ttyS ; then
580           local option="${serial##*,}"
581           # default (works for kvm & CO):
582           local speed="115200,57600,38400,19200,9600,4800,2400,1200";
583           # ... unless overriden by command line:
584           case "$option" in
585             115200*) speed=115200 ;;
586              57600*) speed=57600 ;;
587              38400*) speed=38400 ;;
588              19200*) speed=19200 ;;
589               9600*) speed=9600 ;;
590               4800*) speed=4800 ;;
591               2400*) speed=2400 ;;
592               1200*) speed=1200 ;;
593           esac
594           eindent
595             einfo "Activating console login on device ${device} with speed ${speed}."
596             local number="${device#ttyS}"
597             sed -i "/^T$number:/d;/^#grmlserial#/iT$number:23:respawn:/bin/bash -c \"/sbin/getty -L $device -l /usr/bin/zsh-login $speed vt100 || sleep 30\"" /etc/inittab
598             eend $?
599             telinitq="1"
600           eoutdent
601         fi
602         ;;
603     esac
604     this="${line%%[$ws]*}"
605     line="${line#*[$ws]}"
606   done
607
608   if [ -n "$telinitq" ]; then
609     /sbin/telinit q
610   fi
611   eend $?
612 fi
613 }
614 # }}}
615
616 # {{{ Bring up loopback interface now
617 config_local_net(){
618  if [ -z "$INSTALLED" ] ; then
619     if grep -q 'iface lo inet loopback' /etc/network/interfaces 2>/dev/null ; then
620        grep -q lo=lo /etc/network/run/ifstate 2>/dev/null || ifup lo
621     else
622        ifconfig lo up
623     fi
624  fi
625 }
626 # }}}
627
628 # {{{ copy passwd-lockfile to ramdisk (fix unionfs-behaviour)
629 # otherwise we will get: passwd: Authentication token lock busy
630 config_fix_passwd(){
631  if [ -z "$INSTALLED" ] ; then
632   touch /etc/.pwd.lock
633  fi
634 }
635 # }}}
636
637 # {{{ CD Checker
638 config_testcd(){
639 if [ -n "$TESTCD" ]; then
640    einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
641    einfo "Reading files and checking against GRML/md5sums, this may take a while..."
642    echo -n "${RED}"
643
644    if [ -n "${LIVECD_PATH}"/GRML ] ; then
645       ( cd "${LIVECD_PATH}"/GRML ; rm -f /tmp/md5sum.log ; md5sum -c md5sums 2>&1 | tee /tmp/md5sum.log ; RC=$? )
646    else
647       echo "${RED} *** Error: Could not find md5sum file.                           ***"
648    fi
649
650    if [ "$RC" = "0" ]; then
651       einfo "Everything looks OK" ; eend 0
652    else
653       eerror 'Checksum failed for theses files:' ; eend 1
654       egrep -v '(^md5sum:|OK$)' /tmp/md5sum.log
655       eerror 'Data on the grml medium is possibly incomplete/damaged or...'
656       eerror '... RAM of your computer is broken.' ; eend 1
657       einfon "Hit return to continue, or press the reset button to quit."
658      read a
659    fi
660
661    eend 0
662 fi
663 }
664 # }}}
665
666 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
667 config_blacklist(){
668 if checkbootparam 'blacklist' ; then
669  if [ -z "$INSTALLED" ]; then
670   einfo "Bootoption blacklist found."
671   BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
672   BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
673   if [ -n "$BLACK" ] ; then
674     for module in $(echo ${BLACK//,/ }) ; do
675         einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
676         echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
677         echo "blacklist $module"     >> "$BLACKLIST_FILE"
678         echo "alias     $module off" >> "$BLACKLIST_FILE"
679         echo "# end   entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
680     done
681   else
682    eerror "No given module for blacklist found. Blacklisting will not work therefore."
683   fi
684  else
685   ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
686   eindent
687    einfo "Please blacklist the module(s) manually using the 'blacklist' script."
688   eoutdent
689  fi
690 fi
691 }
692 # }}}
693
694 # {{{ ACPI
695 config_acpi_apm(){
696 if [ -d /proc/acpi ]; then
697   if checkbootparam 'noacpi'; then
698     ewarn "Skipping ACPI Bios detection as requested via noacpi on boot commandline." ; eend 0
699   elif checkbootparam 'nogrmlacpi' ; then
700     ewarn "Skipping ACPI Bios detection as requested via nogrmlacpi on boot commandline." ; eend 0
701   else
702     einfo "ACPI Bios found, activating modules (disable via bootoption noacpi / nogrmlacpi): "
703     eindent
704     found=""
705     for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
706       basename="${a##*/}"
707       basename="${basename%%.*}"
708       case "$basename" in *_acpi)
709        egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
710       esac
711       modprobe $basename >>$DEBUG 2>&1 && found="yes"
712       local BASE="$BASE $basename"
713     done
714     if [ -n "$found" ] ; then
715       einfo "$BASE"  ; eend 0
716     else
717       ewarn "(none)" ; eend 1
718     fi
719     if ! ps x 2>>$DEBUG | grep -q /usr/sbin/acpid ; then
720       if ! [ -r /var/run/dbus/pid ] ; then
721         einfo "Starting acpi daemon."
722         /etc/init.d/acpid start >>$DEBUG 2>&1 ; eend $?
723       else
724         eerror "acpid error: it seems you are running d-bus/hal, but acpid needs to be started before d-bus."
725         eerror "Solution: please activate acpid via /etc/runlevel.conf"
726         eend 1
727       fi
728     else
729       ewarn "acpi daemon already running."
730       eend 0
731     fi
732     eoutdent
733   fi
734 else
735 # APM
736   if checkbootparam 'noapm'; then
737     ewarn "Skipping APM Bios detection as requested on boot commandline." ; eend 0
738   else
739     modprobe apm power_off=1 >>$DEBUG 2>&1
740     if [ "$?" = "0" ] ; then
741        if [ -x /etc/init.d/apmd ] ;then
742           einfo "APM Bios found, enabling power management functions."
743           /etc/init.d/apmd start ; eend $?
744        fi
745     else
746       eerror "Loading apm module failed." ; eend 1
747     fi
748   fi
749 fi
750 }
751 # }}}
752
753 # {{{ AGP
754 config_agp(){
755 if checkbootparam 'forceagp' ; then
756 # Probe for AGP. Hope this can fail safely
757   grep -q "AGP" "/proc/pci" 2>>$DEBUG && { modprobe agpgart || modprobe agpgart agp_try_unsupported=1; } >>$DEBUG 2>&1 && einfo "AGP bridge detected." ; eend 0
758 fi
759 }
760 # }}}
761
762 # {{{ Collect partitions from /proc/partitions first for enabling DMA
763 check_partitions(){
764 partitions=""
765 IDEDISKS=""
766 while read major minor blocks partition relax; do
767   partition="${partition##*/}"
768   [ -z "$partition" -o ! -e "/dev/$partition" ] && continue
769   case "$partition" in
770     hd?) IDEDISKS="$IDEDISKS $partition";;                # IDE  Harddisk, entire disk
771     sd?) ;;                                               # SCSI Harddisk, entire disk
772 #    [hs]d*) partitions="$partitions /dev/$partition";;    # IDE or SCSI disk partition
773     [hs]d*|ub*) partitions="$partitions /dev/$partition";;    # IDE, USB or SCSI disk partition
774   esac
775 done <<EOT
776 $(awk 'BEGIN{old="__start"}{if($0==old){exit}else{old=$0;if($4&&$4!="name"){print $0}}}' /proc/partitions)
777 EOT
778 }
779 check_partitions >/dev/null 2>&1 # avoid output "check_partitions:3: read-only file system"
780 # }}}
781
782 # {{{ Enable DMA for all IDE drives now if not disabled
783 # Notice: Already done by linuxrc, but make sure it's done also on harddisk-installed systems
784 config_dma(){
785 if checkbootparam 'nodma'; then
786   ewarn "Skipping DMA accelleration as requested on boot commandline." ; eend 0
787 else
788   for d in $(cd /proc/ide 2>>$DEBUG && echo hd[a-z]); do
789     if test -d /proc/ide/$d; then
790       if egrep -q 'using_dma[ \t]+0' /proc/ide/$d/settings 2>>$DEBUG; then
791         MODEL="$(cat /proc/ide/$d/model 2>>$DEBUG)"
792         test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]"
793         einfo "Enabling DMA acceleration for: ${WHITE}$d        ${YELLOW}[${MODEL}]${NORMAL}"
794         echo "using_dma:1" >/proc/ide/$d/settings
795         eend 0
796       fi
797     fi
798   done
799 fi
800 }
801 # }}}
802
803 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
804 config_fstab(){
805
806 NOSWAP="yes" # we do not use swap by default!
807 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
808    NOSWAP=''
809    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
810 fi
811
812 # Scan for swap, config, homedir - but only in live-mode
813 if [ -z "$INSTALLED" ] ; then
814    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
815    GRML_IMG=""
816    GRML_SWP=""
817    HOMEDIR="$(getbootparam 'home')"
818    if [ -n "$partitions" ]; then
819       while read p m f relax; do
820         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
821         partoptions="users,exec"
822         fnew=""
823         # it's a swap partition?
824         case "$f" in swap)
825           eindent
826           if [ -n "$NOSWAP" ]; then
827              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
828              eend 0
829           else
830              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
831                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
832                      if [ -n "$ANYSWAP" ] ; then
833                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
834                         swapon $p 2>>$DEBUG ; eend $?
835                      else
836                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
837                      fi
838                      ;;
839                    *)
840                      if [[ "$p" == LABEL* ]] ; then
841                         p=$(blkid -t $p | awk -F: '{print $1}')
842                      fi
843                      if grep -q $p /proc/swaps ; then
844                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
845                      else
846                         if [ -b "$p" ] ; then
847                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
848                         swapon $p 2>>$DEBUG ; eend $?
849                         else
850                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
851                         fi
852                      fi
853                      ;;
854              esac # dd-check
855           fi # -n "$NOSWAP
856           eoutdent
857           continue
858           ;;
859         esac # it's a swap partition?
860
861         # mount read-only
862         MOUNTOPTS="ro"
863         case "$f" in
864           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
865           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
866           *) continue ;;
867           # *) NONEFOUND='1'; continue ;;
868         esac
869
870         # use a swapfile
871         if [ -z "$NOSWAP" ] ; then
872            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
873            # Activate swapfile, if exists
874            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
875         fi
876         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
877            mount -o remount,rw $m && MOUNTED=1
878            if swapon "$SWAPFILE" 2>>$DEBUG ; then
879               eindent
880                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
881               eoutdent
882               fnew="$SWAPFILE swap swap defaults 0 0"
883               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
884               GRML_SWP="$GRML_SWP $SWAPFILE"
885               eend 0
886            fi
887            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
888         fi
889
890         # use a image as home
891         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
892         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
893            if [ -n "$HOMEDIR" ]; then
894               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
895                  continue
896               fi
897            fi
898            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
899               GRML_IMG="$IMAGE"
900               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
901            fi
902         fi
903         eend 0
904
905         # Umount, if not in use
906         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
907
908       done <<EOT
909       $(cat /etc/fstab)
910 EOT
911    fi # -n $partitions
912 fi # -z $INSTALLED
913 }
914 # }}}
915
916 # {{{ Mouse
917 config_mouse(){
918 if [ -n "$MOUSE_DEVICE" ] ; then
919   einfo "Detecting mouse: ${MOUSE_FULLNAME} at ${MOUSE_DEVICE}" ; eend $?
920 fi
921 }
922 # }}}
923
924 # {{{ IPv6 configuration
925 # Load IPv6 kernel module and print IP adresses
926 config_ipv6(){
927 if checkbootparam 'ipv6'; then
928   einfo "Enabling IPv6 as requested on boot commandline (sleeping for 2 seconds)"
929   modprobe ipv6
930   # we probably need some time until stateless autoconfiguration has happened
931   sleep 2
932   NETDEVICES="$(awk -F: '/eth.:|tr.:|wlan.:/{print $1}' /proc/net/dev 2>>$DEBUG)"
933   for DEVICE in `echo "$NETDEVICES"`; do
934     eindent
935       einfo "$DEVICE:"
936       ADDRESSES="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{print $3}')"
937       COUNT="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{ sum += 1};END {print sum }')"
938       eindent
939         for ADDR in `echo "$ADDRESSES"` ; do
940             einfo "$ADDR"
941         done
942         if [ "$COUNT" -eq "0" ] ; then
943            einfo "(none)" ; eend 1
944         fi
945       eoutdent
946     eoutdent
947   done
948   eend 0
949 fi
950 }
951 # }}}
952
953 # {{{ CPU-detection
954 config_cpu(){
955 if checkbootparam 'nocpu'; then
956   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
957   return 0
958 fi
959
960 if [[ $(grep -c processor /proc/cpuinfo) -gt 1 ]] ; then
961    einfo "Detecting CPU:"
962    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)
963    echo $CPU | sed 's/ \{1,\}/ /g'
964    eend 0
965 else
966    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
967 fi
968
969 # Virtual Box supports ACPI and laptop-detect would return with '0', so check for it:
970 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
971    einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0
972    return 0
973 fi
974
975 if [ -x /etc/init.d/loadcpufreq ] ; then
976    einfo "Trying to set up cpu frequency scaling:"
977    eindent
978    SKIP_CPU_GOVERNOR=''
979    LOADCPUFREQ=$(mktemp)
980    /etc/init.d/loadcpufreq start >"$LOADCPUFREQ" 2>&1 ; RC=$?
981    if grep -q FATAL "$LOADCPUFREQ" ; then
982       eindent
983         SKIP_CPU_GOVERNOR=1
984         oldIFS="$IFS"
985         IFS="
986 "
987          for line in $(grep FATAL "$LOADCPUFREQ" | sed 's/.*FATAL: //; s/ (.*)//') ; do
988              eerror "$line" ; eend $RC
989          done
990          IFS="$oldIFS"
991       eoutdent
992    elif grep -q done "$LOADCPUFREQ" ; then
993       MODULE=$(grep done "$LOADCPUFREQ" | sed 's/.*done (\(.*\))./\1/')
994       if [ -n "$MODULE" -a "$MODULE" != none ]; then
995          einfo "Loading cpufreq kernel module $MODULE" ; eend 0
996       else
997          ewarn "Could not find an appropriate kernel module for cpu frequency scaling." ; eend 1
998       fi
999    fi
1000
1001    rm -f $LOADCPUFREQ
1002
1003    if [ -z "$SKIP_CPU_GOVERNOR" ] ; then
1004       einfo "Loading cpufreq_ondemand, setting ondemand governor"
1005       RC=0
1006       if modprobe cpufreq_ondemand ; RC=$? ; then
1007          for file in $(find /sys/devices/system/cpu/ -name scaling_governor 2>/dev/null) ; do
1008             echo ondemand > $file
1009          done
1010       fi
1011       eend $RC
1012    fi # cpu-governor
1013
1014    eoutdent
1015 fi
1016 }
1017 # }}}
1018
1019 # {{{ autostart of ssh
1020 config_ssh(){
1021 if checkbootparam 'ssh' ; then
1022    SSH_PASSWD=''
1023    SSH_PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
1024    einfo "Bootoption ssh found, trying to set password for user grml."
1025    eindent
1026    if [ -z "$SSH_PASSWD" ] ; then
1027       if [ -x /usr/bin/apg ] ; then
1028          SSH_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1029       elif [ -x /usr/bin/gpw ] ; then
1030          SSH_PASSWD="$(gpw 1)"
1031       elif [ -x /usr/bin/pwgen ] ; then
1032          SSH_PASSWD="$(pwgen -1 8)"
1033       elif [ -x /usr/bin/hexdump ] ; then
1034          SSH_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1035       elif [ -n "$RANDOM" ] ; then
1036          SSH_PASSWD="grml${RANDOM}"
1037       else
1038          SSH_PASSWD=''
1039          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1040          eend 1
1041       fi
1042
1043       if [ -n "$SSH_PASSWD" ] ; then
1044          ewarn "No given password for ssh found. Using random password: $SSH_PASSWD" ; eend 0
1045       fi
1046    fi
1047    eoutdent
1048
1049    # finally check if we have a password we can use:
1050    if [ -n "$SSH_PASSWD" ] ; then
1051       # chpasswd sucks, seriously.
1052       if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1053         echo "grml:$SSH_PASSWD" | chpasswd -m
1054       else
1055         echo "grml:$SSH_PASSWD" | chpasswd
1056       fi
1057    fi
1058
1059    einfo 'Starting secure shell server in background.'
1060    /etc/init.d/rmnologin start >>$DEBUG 2>>$DEBUG
1061    /etc/init.d/ssh start >>$DEBUG 2>>$DEBUG &
1062    eend $?
1063
1064    eindent
1065    ewarn 'Warning: please change the password for user grml as soon as possible!'
1066    eoutdent
1067 fi
1068 }
1069 # }}}
1070
1071 # {{{ autostart of x11vnc
1072 config_vnc(){
1073
1074 USER=grml # TODO: make it dynamically configurable
1075 if checkbootparam 'vnc' ; then
1076    VNC_PASSWD=''
1077    VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)"
1078    einfo "Bootoption vnc found, trying to set password for user $USER."
1079    eindent
1080    if [ -z "$VNC_PASSWD" ] ; then
1081       if [ -x /usr/bin/apg ] ; then
1082          VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1083       elif [ -x /usr/bin/gpw ] ; then
1084          VNC_PASSWD="$(gpw 1)"
1085       elif [ -x /usr/bin/pwgen ] ; then
1086          VNC_PASSWD="$(pwgen -1 8)"
1087       elif [ -x /usr/bin/hexdump ] ; then
1088          VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1089       elif [ -n "$RANDOM" ] ; then
1090          VNC_PASSWD="${USER}${RANDOM}"
1091       else
1092          VNC_PASSWD=''
1093          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1094          eend 1
1095       fi
1096
1097       if [ -n "$VNC_PASSWD" ] ; then
1098          ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0
1099       fi
1100    fi
1101    eoutdent
1102
1103    # finally check if we have a password we can use:
1104    if [ -n "$VNC_PASSWD" ] ; then
1105
1106       VNCDIR="/home/${USER}/.vnc"
1107       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1108
1109       if [ ! -x /usr/bin/x11vnc ] ; then
1110          eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package."
1111          eend 1
1112       else
1113          /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $?
1114          /bin/chown -R "$USER": "$VNCDIR"
1115       fi
1116    fi
1117    if checkbootparam 'vnc_connect' ; then
1118       VNC_CONNECT=''
1119       VNC_CONNECT="$(getbootparam 'vnc_connect' 2>>$DEBUG)"
1120       einfo "Bootoption vnc_connect found, will start vnc with connect to $VNC_CONNECT."
1121       #store the options in a file
1122       VNCDIR="/home/${USER}/.vnc"
1123       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1124       echo " --connect $VNC_CONNECT " >> $VNCDIR/options
1125    fi
1126 fi
1127 }
1128 # }}}
1129
1130 # {{{ set password for user grml
1131 config_passwd(){
1132 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1133   einfo "Bootoption passwd found."
1134   PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1135   if [ -n "$PASSWD" ] ; then
1136     echo "grml:$PASSWD" | chpasswd -m ; eend $?
1137   else
1138     eerror "No given password for ssh found. Autostart of SSH will not work." ; eend 1
1139   fi
1140   eindent
1141     ewarn "Warning: please change the password for user grml set via bootparameter as soon as possible!"
1142   eoutdent
1143 fi
1144 }
1145 # }}}
1146
1147 # {{{ Sound
1148 config_mixer () {
1149    if ! [ -x /usr/bin/amixer ] ; then
1150       eerror "amixer binary not available. Can not set sound volumes therefore."
1151       eend 1
1152    else
1153       if ! [ -r /proc/asound/cards ] ; then
1154          ewarn "No soundcard present, skipping mixer settings therefore."
1155          eend 0
1156          return
1157       fi
1158
1159       for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do
1160          einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\""
1161          eindent
1162
1163          if checkbootparam 'vol' ; then
1164             VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1165             if [ -z "$VOL" ] ; then
1166                eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)."
1167                VOL='75'
1168                eend 1
1169             fi
1170          else
1171             VOL='75'
1172          fi
1173
1174          if checkbootparam 'nosound' ; then
1175             einfo "Muting sound devices on request."
1176             ERROR=$(amixer -q set Master mute)
1177             RC=$?
1178             if [ -n "$ERROR" ] ; then
1179                eindent
1180                eerror "Problem muting sound devices: $ERROR"
1181                eoutdent
1182             fi
1183             eend $RC
1184          elif [ -z "$INSTALLED" ] ; then
1185             einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1186
1187             if checkbootparam 'micvol' ; then
1188                MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1189             else
1190                MICVOL=0
1191             fi
1192
1193             for CONTROL in Master PCM ; do
1194                if amixer -q | grep -q "Simple mixer control '$CONTROL'" ; then
1195                   amixer -q set "${CONTROL}" "${VOL}"%
1196                   eend $?
1197                fi
1198             done
1199
1200             if [ ${MICVOL} -ne 0 ] ; then
1201                einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1202                amixer -q set "Mic" $MICVOL &> /dev/null
1203                eend $?
1204             fi
1205          fi # checkbootparam 'nosound'
1206          eoutdent
1207       done
1208    fi
1209 }
1210 # }}}
1211
1212 # {{{ modem detection
1213 config_modem(){
1214 if checkbootparam 'nomodem'; then
1215   ewarn "Skipping check for AC97 modem controller as requested on boot commandline." ; eend 0
1216 else
1217   if [ -x /etc/init.d/sl-modem-daemon ] ; then
1218      if lspci | grep Intel | grep -q "AC'97 Modem Controller" ; then
1219         einfo "AC97 modem controller detected. Start it running 'Start sl-modem-daemon'."
1220         eend 0
1221      fi
1222   fi
1223 fi
1224 }
1225 # }}}
1226
1227 # {{{ wondershaper
1228 config_wondershaper(){
1229  if checkbootparam 'wondershaper' ; then
1230     WONDER="$(getbootparam 'wondershaper' 2>>$DEBUG)"
1231     CMD=wondershaper
1232     DEVICE=""
1233     DOWNSTREAM=""
1234     UPSTREAM=""
1235     if [ -n "$WONDER" ]; then
1236       # Extra options
1237       DEVICE="${WONDER%%,*}"
1238       R="${WONDER#*,}"
1239       if [ -n "$R" -a "$R" != "$WONDER" ]; then
1240         WONDER="$R"
1241         DOWNSTREAM="${WONDER%%,*}"
1242         R="${WONDER#*,}"
1243         if [ -n "$R" -a "$R" != "$WONDER" ]; then
1244           WONDER="$R"
1245           UPSTREAM="${WONDER%%,*}"
1246           R="${WONDER#*,}"
1247         fi
1248       fi
1249     fi
1250     [ -n "$DEVICE" ]     && CMD="$CMD $DEVICE"
1251     [ -n "$DOWNSTREAM" ] && CMD="$CMD $DOWNSTREAM"
1252     [ -n "$UPSTREAM" ]   && CMD="$CMD $UPSTREAM"
1253     einfo "Starting wondershaper (${CMD}) in background."
1254     ( sh -c $CMD & ) && eend 0
1255  fi
1256 }
1257 # }}}
1258
1259 # {{{ syslog-ng
1260 config_syslog(){
1261  if checkbootparam 'nosyslog'; then
1262     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1263  else
1264     SYSLOGD=''
1265     [ -x /etc/init.d/syslog-ng ] && SYSLOGD='syslog-ng'
1266     [ -x /etc/init.d/rsyslog   ] && SYSLOGD='rsyslog'
1267     [ -x /etc/init.d/dsyslog   ] && SYSLOGD='dsyslog'
1268     [ -x /etc/init.d/sysklogd  ] && SYSLOGD='sysklogd'
1269     [ -x /etc/init.d/inetutils-syslogd ] && SYSLOGD='inetutils-syslogd'
1270
1271     if [ -z "$SYSLOGD" ] ; then
1272        eerror "No syslog daemon found." ; eend 1
1273     else
1274        einfo "Starting $SYSLOGD in background."
1275        /etc/init.d/$SYSLOGD start >>$DEBUG &
1276        eend 0
1277     fi
1278  fi
1279 }
1280 # }}}
1281
1282 # {{{ gpm
1283 config_gpm(){
1284  if checkbootparam 'nogpm'; then
1285   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1286  else
1287    if ! [ -r /dev/input/mice ] ; then
1288       eerror "No mouse found - not starting GPM." ; eend 1
1289    else
1290       einfo "Starting gpm in background."
1291       /etc/init.d/gpm start >>$DEBUG &
1292       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start >>$DEBUG ) &
1293       eend 0
1294    fi
1295  fi
1296 }
1297 # }}}
1298
1299 # {{{ services
1300 config_services(){
1301  if checkbootparam 'services' ; then
1302     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1303     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1304     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1305     for service in $(echo -e $SERVICELIST) ; do
1306       # support running (custom) init scripts in non-blocking mode
1307       # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1308       if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1309         einfo "Starting service ${service}."
1310         /etc/init.d/${service} start >>$DEBUG
1311       else
1312         einfo "Starting service ${service} in background."
1313         /etc/init.d/${service} start >>$DEBUG &
1314       fi
1315     done
1316     eend $?
1317  fi
1318 }
1319 # }}}
1320
1321 # {{{ remote files
1322 get_remote_file() {
1323   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1324   SOURCE=$(eval echo "$1")
1325   TARGET="$2"
1326   getconfig() {
1327   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1328        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1329   }
1330   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1331   counter=10
1332   while ! getconfig && [[ "$counter" != 0 ]] ; do
1333     echo -n "Sleeping for 1 second and trying to get config again... "
1334     counter=$(( counter-1 ))
1335     echo "$counter tries left" ; sleep 1
1336   done
1337   if [ -s "$TARGET" ] ; then
1338     einfo "Downloading was successfull." ; eend 0
1339     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1340     md5sum ${TARGET} ; eend 0
1341     return 0;
1342   else
1343     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1344     return 1;
1345  fi
1346 }
1347 # }}}
1348
1349 # {{{ config files
1350 config_netconfig(){
1351  if checkbootparam 'netconfig' ; then
1352   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1353   CONFIGFILE='/tmp/netconfig.grml'
1354
1355   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1356     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1357   fi
1358
1359  fi
1360 }
1361 # }}}
1362
1363 # {{{ remote scripts
1364 config_netscript() {
1365  if checkbootparam 'netscript' ; then
1366   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1367   SCRIPTFILE='/tmp/netscript.grml'
1368
1369   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1370     chmod +x ${SCRIPTFILE}
1371     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1372   fi
1373
1374  fi
1375 }
1376 # }}}
1377
1378 # {{{ fix/workaround for unionfs
1379 fix_unionfs(){
1380   if [ -z "$INSTALLED" ]; then
1381    touch /var/cache/apt/*cache.bin
1382   fi
1383 }
1384 # }}}
1385
1386 # {{{ start X window system via grml-x
1387 config_x_startup(){
1388 # make sure we start X only if startx is used *before* a nostartx option
1389 # so it's possible to disable automatic X startup using nostart
1390 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1391  if [ -x "$(which X)" ] ; then
1392   if [ -z "$INSTALLED" ] ; then
1393    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1394    if [ -z "$WINDOWMANAGER" ] ; then
1395      einfo "No window manager specified. Taking ${WHITE}wm-ng${NORMAL} as default." && eend 0
1396      WINDOWMANAGER="wm-ng"
1397    else
1398      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1399    fi
1400    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1401    config_userfstab || fstabuser='grml'
1402  cat>|/etc/init.d/xstartup<<EOF
1403 #!/bin/sh
1404 su $fstabuser -c "/usr/bin/grml-x $WINDOWMANAGER"
1405 EOF
1406    chmod 755 /etc/init.d/xstartup
1407
1408    # adjust inittab for xstartup
1409    if grep -q '^6:' /etc/inittab ; then
1410       sed -i 's|^6:.*|6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/bin/zsh-login" >/dev/tty6 2>\&1 </dev/tty6|' /etc/inittab
1411    else # just append tty6 to inittab if no definition is present:
1412       echo '6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/bin/zsh-login" >/dev/tty6 2>&1 < /dev/tty6' >> /etc/inittab
1413    fi
1414
1415    /sbin/telinit q ; eend $?
1416
1417    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1418       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1419    else
1420       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1421    fi
1422
1423   else
1424     eerror "We are not running in live mode - startx will not work, skipping it."
1425     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1426   fi
1427  else
1428    eerror "/usr/X11R6/bin/X is not present on this grml flavour."
1429    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1430  fi
1431 fi
1432 }
1433 # }}}
1434
1435 # {{{ configuration framework
1436 config_extract(){
1437 if checkbootparam 'extract' ; then
1438  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1439  EXTRACTOPTIONS="-- -x $EXTRACT"
1440 fi
1441 }
1442
1443 config_finddcsdir() {
1444 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1445 #    on the command line, nothing is changed and the dcs files are
1446 #    searched within the .iso, $dcs-dir is set to the root directory
1447 #    within the .iso
1448 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1449 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1450 #    set, $dcs-dir is set to the root directory within the .iso.
1451 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1452 #    foo, even if a GRMLCFG partition is present.
1453 DCSDIR=""
1454 DCSMP="/mnt/grml"
1455 # autoconfig, see issue673
1456 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1457 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1458 if checkbootparam 'noautoconfig' || checkbootparam 'forensic' ; then
1459   ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1460 else
1461   if [ -z "$INSTALLED" ] ; then
1462     if checkbootparam 'myconfig' ; then
1463       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1464       if [ -z "$DCSDEVICE" ]; then
1465         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1466       fi # [ -z "$DCSDEVICE" ]
1467     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1468       einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1469       eindent
1470       # We do need the following fix so floppy disk is available to blkid in any case :-/
1471       if [ -r /dev/fd0 ] ; then
1472         einfo "Floppy device detected. Trying to access floppy disk."
1473         if timeout 4 dd if=/dev/fd0 of=/dev/null bs=512 count=1 >>$DEBUG 2>&1 ; then
1474            blkid /dev/fd0 >>$DEBUG 2>&1
1475         fi
1476       fi
1477       DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1478       if [ -n "$DCSDEVICE" ]; then
1479         DCSMP="/mnt/grmlcfg"
1480       fi
1481       eoutdent
1482     fi
1483
1484     # if not specified/present then assume default:
1485     if [ -z "$DCSDEVICE" ]; then
1486       DCSDIR="/live/image"
1487     else
1488       eindent
1489       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1490       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1491       if [ -n "$DCSDIR" ]; then
1492         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1493       else
1494         [ -d $DCSMP ] || mkdir $DCSMP
1495         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1496         mount -o ro -t auto $DCSDEVICE  $DCSMP ; RC="$?"
1497         if [[ $RC == 0 ]]; then
1498           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1499         else
1500           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1501         fi
1502         DCSDIR="$DCSMP"
1503       fi
1504       eoutdent
1505     fi
1506   fi
1507 fi
1508
1509 if [ -n "$DCSDIR" -a "$DCSDIR" != "/live/image" ] ; then
1510   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1511 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1512   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1513 fi
1514 }
1515
1516
1517 config_partconf() {
1518 if checkbootparam 'partconf' ; then
1519  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1520  if [ -n "$MOUNTDEVICE" ]; then
1521    [ -d /mnt/grml ] || mkdir /mnt/grml
1522    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1523     if [[ $RC == 0 ]]; then
1524       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1525       einfo "Copying files from $MOUNTDEVICE over grml system."
1526       for file in `cat /etc/grml/partconf` ; do
1527         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1528         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1529       done && eend 0
1530     else
1531       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1532     fi # mount $MOUNTDEVICE
1533    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1534  else
1535    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1536  fi # [ -n "$MOUNTDEVICE" ]
1537 fi
1538 }
1539 # }}}
1540
1541 # {{{ /cdrom/.*-options
1542 config_debs(){
1543 if checkbootparam 'debs' ; then
1544    iszsh && setopt localoptions shwordsplit
1545    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1546    if [ -z "$DEBS" ] ; then
1547       DEBS="*.deb"
1548    fi
1549    if ! echo $DEBS | grep -q '/'; then
1550      # backwards compatibility: if no path is given get debs from debs/
1551      DEBS="debs/$DEBS"
1552    fi
1553    einfo "Tring to install debian package(s) ${DEBS}"
1554    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1555    dpkg -i $DEBS ; eend $?
1556 fi
1557 }
1558
1559 config_scripts(){
1560 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1561    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1562    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1563      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1564    fi
1565    if ! echo $SCRIPTS | grep -q '/'; then
1566      # backwards compatibility: if no path is given get scripts from scripts/
1567      SCRIPTS="scripts/$SCRIPTS"
1568    fi
1569    if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1570      # we are executing from a GRMLCFG labeled fs
1571      # kick everything we have done before and start over
1572      SCRIPTS="$(cd ${DCSDIR}; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1573    fi
1574    if [ -n "$SCRIPTS" ]; then
1575      SCRIPTS="${DCSDIR}/$SCRIPTS"
1576      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1577        einfo "Trying to execute ${SCRIPTS}"
1578        sh -c $SCRIPTS
1579      elif [ -d "$SCRIPTS" ]; then
1580        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1581        run-parts $SCRIPTS
1582      else
1583        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1584        sh -c $SCRIPTS
1585      fi
1586    fi
1587 fi
1588 }
1589
1590 config_config(){
1591 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1592   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1593   if [ -z "$CONFIG" ]; then
1594     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1595   fi
1596   if [ -n "$CONFIG" ]; then
1597     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1598       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1599
1600       cp -a ${DCSDIR}/${CONFIG}/* /
1601     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1602       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1603
1604       cd /
1605       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1606     else
1607       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1608     fi
1609   fi
1610 fi
1611 }
1612 # }}}
1613
1614 # {{{ confing_umount_dcsdir
1615 config_umount_dcsdir(){
1616    # umount $DCSMP if it was mounted by finddcsdir
1617    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1618 }
1619 # }}}
1620
1621 # {{{ mypath
1622 config_mypath(){
1623 if checkbootparam 'mypath' ; then
1624    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1625    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1626    touch /etc/grml/my_path
1627    chmod 644 /etc/grml/my_path
1628    # make sure the directories exist:
1629    eindent
1630    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1631        if ! [ -d "$i" ] ; then
1632           einfo "Creating directory $i"
1633           mkdir -p "$i" ; eend $?
1634        fi
1635    done
1636    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1637    eoutdent
1638 fi
1639 }
1640 # }}}
1641
1642 # {{{ distcc
1643 config_distcc(){
1644 if checkbootparam 'distcc' ; then
1645  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
1646  if [ -n "$OPTIONS" ]; then
1647     NET=""
1648     INTERFACE=""
1649     if [ -n "$OPTIONS" ]; then
1650       NET="${OPTIONS%%,*}"
1651       R="${OPTIONS#*,}"
1652       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1653         OPTIONS="$R"
1654         INTERFACE="${OPTIONS%%,*}"
1655         R="${OPTIONS#*,}"
1656       fi
1657     fi
1658  fi
1659  CONFIG=/etc/default/distcc
1660  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
1661  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
1662
1663  if [ -n "$INTERFACE" ] ; then
1664    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1665
1666    counter=10
1667    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
1668      counter=$(( counter-1 ))
1669      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
1670      sleep 3
1671      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1672    done
1673  fi
1674
1675  if [ -n "$IP" ] ; then
1676    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
1677
1678    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
1679    eindent
1680     id distccd >/dev/null 2>&1 || \
1681     (
1682       einfo "Creating distcc user" ; \
1683       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
1684     )
1685
1686     einfo "Starting distcc for network ${NET}, listening on ${IP}."
1687    /etc/init.d/distcc start >/dev/null ; eend $?
1688    eoutdent
1689  else
1690    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
1691  fi
1692 fi
1693
1694 if checkbootparam 'gcc'; then
1695  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
1696  eindent
1697  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
1698  eoutdent
1699  rm -f /usr/bin/gcc
1700  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
1701 fi
1702
1703 if checkbootparam 'gpp'; then
1704  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
1705  eindent
1706   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
1707   if [ -x /usr/bin/g++-${GPP} ] ; then
1708      rm -f /usr/bin/g++
1709      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
1710   fi
1711   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
1712   if [ -x /usr/bin/cpp-${GPP} ] ; then
1713      rm -f /usr/bin/cpp
1714      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
1715   fi
1716  eoutdent
1717 fi
1718
1719 }
1720 # }}}
1721
1722 # {{{ load modules
1723 # Notice: use it only on live-cd system, if running from harddisk please
1724 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
1725 # in /etc/runlevel.conf
1726 config_modules(){
1727 MODULES_FILE=/etc/grml/modules
1728 if checkbootparam 'nomodules' ; then
1729   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
1730 elif [ -z "$INSTALLED" ]; then
1731  if [ -r $MODULES_FILE ] ; then
1732   einfo "Loading modules specified in ${MODULES_FILE}:"
1733   eindent
1734   grep '^[^#]' $MODULES_FILE | \
1735   while read module args; do
1736     [ "$module" ] || continue
1737       einfo "${module}"
1738       modprobe $module $args ; eend $?
1739   done
1740   eoutdent
1741  else
1742   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
1743  fi
1744 fi
1745 }
1746 # }}}
1747
1748 # {{{ 915resolution
1749 config_915resolution(){
1750 if checkbootparam '915resolution' ; then
1751  OPTIONS="$(getbootparam '915resolution' 2>>$DEBUG)"
1752   if [ -x /usr/sbin/915resolution ]; then
1753     CMD=915resolution
1754     MODE=""
1755     XRESO=""
1756     YRESO=""
1757     if [ -n "$OPTIONS" ]; then
1758       # Extra options
1759       MODE="${OPTIONS%%,*}"
1760       R="${OPTIONS#*,}"
1761       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1762         OPTIONS="$R"
1763         XRESO="${OPTIONS%%,*}"
1764         R="${OPTIONS#*,}"
1765         if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1766           OPTIONS="$R"
1767           YRESO="${OPTIONS%%,*}"
1768           R="${OPTIONS#*,}"
1769         fi
1770       fi
1771     fi
1772     einfo "Running 915resolution with options ${MODE} ${XRESO} ${YRESO}."
1773     [ -n "$MODE" ] && [ -n "$XRESO"  ] && [ -n "$YRESO" ]  && ( sh -c "$CMD $MODE $XRESO $YRESO" & )
1774     eend 0
1775   fi
1776 fi
1777 }
1778 # }}}
1779
1780 # {{{ SW-RAID
1781 config_swraid(){
1782   [ -n "$INSTALLED" ] && return 0
1783
1784   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
1785   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1786      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
1787      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1788   else
1789     if ! [ -x /sbin/mdadm ] ; then
1790        eerror "mdadm not available, can not execute it." ; eend 1
1791     else
1792
1793        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1794        # find out whether we have a valid configuration file already
1795        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1796           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1797           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1798           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1799         else
1800           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1801        fi
1802
1803        if ! checkbootparam 'swraid' ; then
1804           eindent
1805           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1806           eoutdent
1807        else
1808           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1809           eindent
1810            IFSOLD=${IFS:-}
1811            IFS='
1812 '
1813            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
1814                case $line in
1815                  *'No arrays found'*)
1816                    ewarn "$line" ; eend 0
1817                    ;;
1818                  *)
1819                    einfo "$line" ; eend 0
1820                    ;;
1821                esac
1822            done
1823            IFS=$IFSOLD
1824          eoutdent
1825
1826          if [ -r /proc/mdstat ] ; then
1827             eindent
1828             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1829             if [ -z "$MDSTAT" ] ; then
1830                ewarn "No active arrays found" ; eend 0
1831             else
1832                IFSOLD=${IFS:-}
1833                IFS='
1834 '
1835                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1836                    einfo "active arrays: $line" ; eend 0
1837                done
1838                IFS=$IFSOLD
1839             fi
1840             eoutdent
1841          fi # /proc/mdstat
1842        fi # bootoption swraid
1843
1844      fi # is /sbin/mdadm executable?
1845   fi # check for bootoptions
1846 }
1847 # }}}
1848
1849 # {{{ dmraid
1850 config_dmraid(){
1851   [ -n "$INSTALLED" ] && return 0
1852
1853   if checkbootparam 'nodmraid' ; then
1854     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1855     return 0
1856   fi
1857
1858   if ! [ -x /sbin/dmraid ] ; then
1859     eerror "dmraid not available, can not execute it." ; eend 1
1860     return
1861   fi
1862
1863   dmraid_wrapper() {
1864     # usage: dmraid_wrapper <dmraid_option>
1865     [ -n "$1" ] || return 1
1866
1867     IFSOLD=${IFS:-}
1868     IFS='
1869 '
1870     eindent
1871
1872     for line in $(dmraid $1 ; echo errcode:$?); do
1873       case $line in
1874         *'no block devices found'*)
1875           einfo "No block devices found" ; eend 0
1876           break
1877           ;;
1878         *'no raid disks'*)
1879           einfo "No active dmraid devices found" ; eend 0
1880           break
1881           ;;
1882         errcode:0)
1883           eend 0;
1884           ;;
1885         errcode:1)
1886           eend 1
1887           ;;
1888         *)
1889           einfo "$line"
1890           ;;
1891       esac
1892     done
1893
1894     eoutdent
1895     IFS=$IFSOLD
1896   }
1897
1898   if checkbootparam 'dmraid' ; then
1899     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1900     if [ "$ACTION" = "off" ] ; then
1901       # Deactivates all active software RAID sets:
1902       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1903       dmraid_wrapper -an
1904     else
1905       # Activate all software RAID sets discovered:
1906       einfo "Activating present dmraid sets (as requested via dmraid):"
1907       dmraid_wrapper -ay
1908     fi
1909
1910     return
1911   fi
1912
1913   # by default (no special bootoptions) discover all software RAID devices:
1914   einfo "Searching for any present dmraid sets:"
1915   dmraid_wrapper -r
1916 }
1917 # }}}
1918
1919 # {{{ LVM (Logical Volumes)
1920 config_lvm(){
1921   [ -n "$INSTALLED" ] && return 0
1922
1923   if checkbootparam 'nolvm' ; then
1924      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1925   else
1926     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
1927     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
1928        eerror "LVM not available, can not execute it." ; eend 1
1929     else
1930        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1931           einfo "You seem to have logical volumes (LVM) on your system."
1932           eindent
1933           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1934           eend 0
1935           if checkbootparam 'lvm' ; then
1936              einfo "Bootoption LVM found. Searching for logical volumes:"
1937              /etc/init.d/lvm2 start ; eend $?
1938           fi
1939           eoutdent
1940        fi
1941     fi # check for lvm binary
1942   fi # check for bootoption nolvm
1943 }
1944 # }}}
1945
1946 # {{{ debnet: setup network based on an existing one found on a partition
1947 config_debnet(){
1948 if checkbootparam 'debnet' ; then
1949  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1950  /usr/sbin/debnet
1951 fi
1952 }
1953 # }}}
1954
1955 # {{{ disable console blanking
1956 config_blanking(){
1957 if checkbootparam 'noblank' ; then
1958   einfo "Bootoption noblank found. Disabling monitor blanking."
1959   setterm -blank 0 ; eend $?
1960 fi
1961 }
1962 # }}}
1963
1964 # {{{ tohd= bootoption
1965 config_tohd()
1966 {
1967   if checkbootparam 'tohd' ; then
1968      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
1969      if [ -z "$TARGET" ] ; then
1970         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
1971         eerror "Please use something like tohd=/dev/sda9." ; eend 1
1972         return 1
1973      fi
1974
1975      if ! [ -b "$TARGET" ] ; then
1976         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
1977         return 1
1978      fi
1979
1980      if grep -q $TARGET /proc/mounts ; then
1981         eerror "$TARGET already mounted, skipping execution of tohd therefore."
1982         eend 1
1983         return 1
1984      fi
1985
1986      local MOUNTDIR=$(mktemp -d)
1987
1988      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
1989         einfo "Copyring live system to $TARGET - this might take a while"
1990         rsync -a --progress /live/image/live $MOUNTDIR
1991         sync
1992         umount "$MOUNTDIR"
1993         eend $?
1994         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
1995      else
1996         eerror "Error when trying to mount $TARGET, sorry."; eend 1
1997         return 1
1998      fi
1999
2000      rmdir "$MOUNTDIR"
2001   fi
2002 }
2003 # }}}
2004
2005 # {{{ grml2hd: automatic installation
2006 config_grml2hd(){
2007
2008 if checkbootparam "grml2hd" || checkbootparam "BOOT_IMAGE=grml2hd" ; then
2009
2010 if checkbootparam 'user' ; then
2011    NEWUSER=''
2012    NEWUSER="$(getbootparam 'user' 2>>$DEBUG)"
2013    sed -i "s/^NEWUSER=.*/NEWUSER=$NEWUSER/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2014 fi
2015
2016 if checkbootparam 'filesystem' ; then
2017    FILESYSTEM=''
2018    FILESYSTEM="$(getbootparam 'filesystem' 2>>$DEBUG)"
2019    sed -i "s/^FILESYSTEM=.*/FILESYSTEM=$FILESYSTEM/" /etc/grml2hd/config || export GRML2HD_FAIL=1
2020 fi
2021
2022 if checkbootparam 'partition' ; then
2023    PARTITION=''
2024    PARTITION="$(getbootparam 'partition' 2>>$DEBUG)"
2025    # notice: the following checks whether the given partition is available, if not the skip
2026    # execution of grml2hd as it might result in data loss...
2027    if [ -r $PARTITION ] ; then
2028       sed -i "s#^PARTITION=.*#PARTITION=$PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2029    else
2030       ewarn "Partition $PARTITION does not exist. Skipping execution of grml2hd therefore." ; eend 1
2031    fi
2032 fi
2033
2034 if checkbootparam 'mbr' ; then
2035    BOOT_PARTITION=''
2036    BOOT_PARTITION="$(getbootparam 'mbr' 2>>$DEBUG)"
2037    sed -i "s#^BOOT_PARTITION=.*#BOOT_PARTITION=$BOOT_PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1
2038 fi
2039
2040 cat>|/usr/bin/grml2hd_noninteractive<<EOF
2041 #!/bin/sh
2042 GRML2HD_NONINTERACTIVE='yes' grml2hd
2043 EOF
2044
2045 chmod 755 /usr/bin/grml2hd_noninteractive
2046 einfo "Bootoption grml2hd found. Running automatic installation via grml2hd using /etc/grml2hd/config." && eend 0
2047 if [ -z "$GRML2HD_FAIL" ] ; then
2048    screen /usr/bin/grml2hd_noninteractive ; einfo "Invoking a shell, just exit to continue booting..." ; /bin/zsh
2049 else
2050    ewarn "There was an error adjusting /etc/grml2hd/config. Skipping execution of grml2hd for security reasons." ; eend 1
2051 fi
2052
2053 fi # if checkbootparam "BOOT_IMAGE=grml2hd ...
2054 }
2055 # }}}
2056
2057 # {{{ debootstrap: automatic installation
2058 config_debootstrap(){
2059
2060 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
2061
2062 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
2063
2064 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
2065    eindent
2066    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
2067    eoutdent
2068    exit 1
2069 fi
2070
2071 if checkbootparam 'target' ; then
2072   TARGET=''
2073   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
2074   # notice: the following checks whether the given partition is available, if not the skip
2075   # execution of grml-debootstrap as it might result in data loss...
2076   if ! [ -r "$TARGET" ] ; then
2077      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
2078   fi
2079 else
2080   eindent
2081   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
2082   eoutdent
2083   exit 1
2084 fi
2085
2086 if checkbootparam 'grub' ; then
2087   GRUB=''
2088   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
2089 fi
2090
2091 if checkbootparam 'groot' ; then
2092   GROOT=''
2093   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
2094 fi
2095
2096 if checkbootparam 'release' ; then
2097   RELEASE=''
2098   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2099 fi
2100
2101 if checkbootparam 'mirror' ; then
2102   MIRROR=''
2103   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2104 fi
2105
2106 if checkbootparam 'boot_append' ; then
2107   BOOT_APPEND=''
2108   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2109 fi
2110
2111 if checkbootparam 'password' ; then
2112   PASSWORD=''
2113   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2114 fi
2115
2116 # now check which options are available
2117 if [ -n "TARGET" ] ; then
2118    TARGETCMD="--target $TARGET"
2119 else
2120    TARGETCMD=''
2121    eindent
2122    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2123    eoutdent
2124    exit 1
2125 fi
2126 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2127 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2128 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2129 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2130 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2131 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2132
2133 # and finally write script and execute it
2134 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2135 #!/bin/sh
2136 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2137 EOF
2138
2139 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2140
2141 screen /usr/bin/grml-debootstrap_noninteractive
2142 einfo "Invoking a shell, just exit to continue booting..."
2143 /bin/zsh
2144
2145 fi # checkbootparam "BOOT_IMAGE=debian2hd
2146 }
2147 # }}}
2148
2149 config_virtualbox_shared_folders() {
2150 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
2151   einfo "VirtualBox detected, trying to set up Shared Folders."
2152   if ! modprobe -l | grep -q vboxsf.ko ; then
2153     ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
2154     eend 0
2155   elif ! [ -x /usr/sbin/VBoxService ] ; then
2156     ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
2157     eend 0
2158   else
2159     eindent
2160
2161       einfo "Loading vboxsf driver."
2162       lsmod | grep -q vboxsf || modprobe vboxsf
2163       eend $?
2164
2165       einfo "Adjusting /dev/vboxguest."
2166       chown root:vboxsf /dev/vboxguest
2167       chmod 660 /dev/vboxguest
2168       eend $?
2169
2170       if [ -n "$CONFIG_FSTAB_USER" ] ; then
2171         fstabuser="$CONFIG_FSTAB_USER"
2172       else
2173         fstabuser=$(getent passwd 1000 | cut -d: -f1)
2174       fi
2175       einfo "Adding $fstabuser to group vboxsf."
2176       adduser grml vboxsf &>/dev/null
2177       eend $?
2178
2179       einfo "Starting VBoxService."
2180       VBoxService >/dev/null &
2181       eend $?
2182
2183     eoutdent
2184   fi
2185 fi
2186 }
2187
2188 # {{{ Support customization
2189 config_distri(){
2190 if checkbootparam 'distri'; then
2191   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2192   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2193      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2194      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2195      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2196      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2197   fi
2198 fi
2199 }
2200 # }}}
2201
2202 ## END OF FILE #################################################################
2203 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3