Remove local_net as it is done by ifupdown nowadays
[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"
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 $TIMEOUT > /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 '/1:/s#/usr/share/grml-scripts/run-welcome#/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/share/grml-scripts/run-welcome $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 # {{{ copy passwd-lockfile to ramdisk (fix unionfs-behaviour)
617 # otherwise we will get: passwd: Authentication token lock busy
618 config_fix_passwd(){
619  if [ -z "$INSTALLED" ] ; then
620   touch /etc/.pwd.lock
621  fi
622 }
623 # }}}
624
625 # {{{ CD Checker
626 config_testcd(){
627 if [ -n "$TESTCD" ]; then
628    einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
629    einfo "Reading files and checking against GRML/md5sums, this may take a while..."
630    echo -n "${RED}"
631
632    if [ -n "${LIVECD_PATH}"/GRML ] ; then
633       ( cd "${LIVECD_PATH}"/GRML ; rm -f /tmp/md5sum.log ; md5sum -c md5sums 2>&1 | tee /tmp/md5sum.log ; RC=$? )
634    else
635       echo "${RED} *** Error: Could not find md5sum file.                           ***"
636    fi
637
638    if [ "$RC" = "0" ]; then
639       einfo "Everything looks OK" ; eend 0
640    else
641       eerror 'Checksum failed for theses files:' ; eend 1
642       egrep -v '(^md5sum:|OK$)' /tmp/md5sum.log
643       eerror 'Data on the grml medium is possibly incomplete/damaged or...'
644       eerror '... RAM of your computer is broken.' ; eend 1
645       einfon "Hit return to continue, or press the reset button to quit."
646      read a
647    fi
648
649    eend 0
650 fi
651 }
652 # }}}
653
654 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
655 config_blacklist(){
656 if checkbootparam 'blacklist' ; then
657  if [ -z "$INSTALLED" ]; then
658   einfo "Bootoption blacklist found."
659   BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
660   BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
661   if [ -n "$BLACK" ] ; then
662     for module in $(echo ${BLACK//,/ }) ; do
663         einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
664         echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
665         echo "blacklist $module"     >> "$BLACKLIST_FILE"
666         echo "alias     $module off" >> "$BLACKLIST_FILE"
667         echo "# end   entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
668     done
669   else
670    eerror "No given module for blacklist found. Blacklisting will not work therefore."
671   fi
672  else
673   ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
674   eindent
675    einfo "Please blacklist the module(s) manually using the 'blacklist' script."
676   eoutdent
677  fi
678 fi
679 }
680 # }}}
681
682 # {{{ ACPI
683 config_acpi(){
684 if checkbootparam 'noacpi'; then
685   ewarn "ACPI: Not loading modules as requested by boot option \"noacpi\"." ; eend 0
686 elif checkbootparam 'nogrmlacpi' ; then
687   ewarn "ACPI: Not loading modules as requested by boot option \"nogrmlacpi\"." ; eend 0
688 elif [ ! -d /proc/acpi ] ; then
689   ewarn "ACPI: Kernel support not present." ; eend 0
690 else
691   einfo "ACPI: Loading modules (disable with boot option noacpi / nogrmlacpi): "
692   eindent
693   found=""
694   for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
695     basename="${a##*/}"
696     basename="${basename%%.*}"
697     case "$basename" in *_acpi)
698      egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
699     esac
700     modprobe $basename >>$DEBUG 2>&1 && found="yes"
701     local BASE="$BASE $basename"
702   done
703   if [ -n "$found" ] ; then
704     einfo "$BASE"  ; eend 0
705   else
706     ewarn "(none)" ; eend 1
707   fi
708   if ! pgrep acpid >/dev/null ; then
709     einfo "Starting acpi daemon."
710     /etc/init.d/acpid start >>$DEBUG 2>&1 ; eend $?
711   else
712     ewarn "acpi daemon already running."
713     eend 0
714   fi
715   eoutdent
716 fi
717 }
718 # }}}
719
720 # {{{ Collect partitions from /proc/partitions first for enabling DMA
721 check_partitions(){
722 partitions=""
723 IDEDISKS=""
724 while read major minor blocks partition relax; do
725   partition="${partition##*/}"
726   [ -z "$partition" -o ! -e "/dev/$partition" ] && continue
727   case "$partition" in
728     hd?) IDEDISKS="$IDEDISKS $partition";;                # IDE  Harddisk, entire disk
729     sd?) ;;                                               # SCSI Harddisk, entire disk
730 #    [hs]d*) partitions="$partitions /dev/$partition";;    # IDE or SCSI disk partition
731     [hs]d*|ub*) partitions="$partitions /dev/$partition";;    # IDE, USB or SCSI disk partition
732   esac
733 done <<EOT
734 $(awk 'BEGIN{old="__start"}{if($0==old){exit}else{old=$0;if($4&&$4!="name"){print $0}}}' /proc/partitions)
735 EOT
736 }
737 check_partitions >/dev/null 2>&1 # avoid output "check_partitions:3: read-only file system"
738 # }}}
739
740 # {{{ Enable DMA for all IDE drives now if not disabled
741 # Notice: Already done by linuxrc, but make sure it's done also on harddisk-installed systems
742 config_dma(){
743 if checkbootparam 'nodma'; then
744   ewarn "Skipping DMA accelleration as requested on boot commandline." ; eend 0
745 else
746   for d in $(cd /proc/ide 2>>$DEBUG && echo hd[a-z]); do
747     if test -d /proc/ide/$d; then
748       if egrep -q 'using_dma[ \t]+0' /proc/ide/$d/settings 2>>$DEBUG; then
749         MODEL="$(cat /proc/ide/$d/model 2>>$DEBUG)"
750         test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]"
751         einfo "Enabling DMA acceleration for: ${WHITE}$d        ${YELLOW}[${MODEL}]${NORMAL}"
752         echo "using_dma:1" >/proc/ide/$d/settings
753         eend 0
754       fi
755     fi
756   done
757 fi
758 }
759 # }}}
760
761 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
762 config_fstab(){
763
764 NOSWAP="yes" # we do not use swap by default!
765 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
766    NOSWAP=''
767    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
768 fi
769
770 # Scan for swap, config, homedir - but only in live-mode
771 if [ -z "$INSTALLED" ] ; then
772    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
773    GRML_IMG=""
774    GRML_SWP=""
775    HOMEDIR="$(getbootparam 'home')"
776    if [ -n "$partitions" ]; then
777       while read p m f relax; do
778         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
779         partoptions="users,exec"
780         fnew=""
781         # it's a swap partition?
782         case "$f" in swap)
783           eindent
784           if [ -n "$NOSWAP" ]; then
785              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
786              eend 0
787           else
788              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
789                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
790                      if [ -n "$ANYSWAP" ] ; then
791                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
792                         swapon $p 2>>$DEBUG ; eend $?
793                      else
794                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
795                      fi
796                      ;;
797                    *)
798                      if [[ "$p" == LABEL* ]] ; then
799                         p=$(blkid -t $p | awk -F: '{print $1}')
800                      fi
801                      if grep -q $p /proc/swaps ; then
802                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
803                      else
804                         if [ -b "$p" ] ; then
805                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
806                         swapon $p 2>>$DEBUG ; eend $?
807                         else
808                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
809                         fi
810                      fi
811                      ;;
812              esac # dd-check
813           fi # -n "$NOSWAP
814           eoutdent
815           continue
816           ;;
817         esac # it's a swap partition?
818
819         # mount read-only
820         MOUNTOPTS="ro"
821         case "$f" in
822           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
823           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
824           *) continue ;;
825           # *) NONEFOUND='1'; continue ;;
826         esac
827
828         # use a swapfile
829         if [ -z "$NOSWAP" ] ; then
830            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
831            # Activate swapfile, if exists
832            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
833         fi
834         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
835            mount -o remount,rw $m && MOUNTED=1
836            if swapon "$SWAPFILE" 2>>$DEBUG ; then
837               eindent
838                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
839               eoutdent
840               fnew="$SWAPFILE swap swap defaults 0 0"
841               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
842               GRML_SWP="$GRML_SWP $SWAPFILE"
843               eend 0
844            fi
845            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
846         fi
847
848         # use a image as home
849         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
850         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
851            if [ -n "$HOMEDIR" ]; then
852               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
853                  continue
854               fi
855            fi
856            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
857               GRML_IMG="$IMAGE"
858               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
859            fi
860         fi
861         eend 0
862
863         # Umount, if not in use
864         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
865
866       done <<EOT
867       $(cat /etc/fstab)
868 EOT
869    fi # -n $partitions
870 fi # -z $INSTALLED
871 }
872 # }}}
873
874 # {{{ Mouse
875 config_mouse(){
876 if [ -n "$MOUSE_DEVICE" ] ; then
877   einfo "Detecting mouse: ${MOUSE_FULLNAME} at ${MOUSE_DEVICE}" ; eend $?
878 fi
879 }
880 # }}}
881
882 # {{{ IPv6 configuration
883 # Load IPv6 kernel module and print IP adresses
884 config_ipv6(){
885 if checkbootparam 'ipv6'; then
886   einfo "Enabling IPv6 as requested on boot commandline (sleeping for 2 seconds)"
887   modprobe ipv6
888   # we probably need some time until stateless autoconfiguration has happened
889   sleep 2
890   NETDEVICES="$(awk -F: '/eth.:|tr.:|wlan.:/{print $1}' /proc/net/dev 2>>$DEBUG)"
891   for DEVICE in `echo "$NETDEVICES"`; do
892     eindent
893       einfo "$DEVICE:"
894       ADDRESSES="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{print $3}')"
895       COUNT="$(ifconfig $DEVICE | awk '/.*inet6 addr:.*/{ sum += 1};END {print sum }')"
896       eindent
897         for ADDR in `echo "$ADDRESSES"` ; do
898             einfo "$ADDR"
899         done
900         if [ "$COUNT" -eq "0" ] ; then
901            einfo "(none)" ; eend 1
902         fi
903       eoutdent
904     eoutdent
905   done
906   eend 0
907 fi
908 }
909 # }}}
910
911 # {{{ CPU-detection
912 config_cpu(){
913 if checkbootparam 'nocpu'; then
914   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
915   return 0
916 fi
917
918 if [[ $(grep -c processor /proc/cpuinfo) -gt 1 ]] ; then
919    einfo "Found CPU:"
920    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)
921    echo $CPU | sed 's/ \{1,\}/ /g'
922    eend 0
923 else
924    einfo "Found 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
925 fi
926
927 # no cpufreq setup inside VirtualBox
928 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
929    einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0
930    return 0
931 fi
932
933 if [ -x /etc/init.d/loadcpufreq ] ; then
934    einfo "Trying to set up cpu frequency scaling:"
935    eindent
936    SKIP_CPU_GOVERNOR=''
937    LOADCPUFREQ=$(mktemp)
938    /etc/init.d/loadcpufreq start >"$LOADCPUFREQ" 2>&1 ; RC=$?
939    if grep -q FATAL "$LOADCPUFREQ" ; then
940       eindent
941         SKIP_CPU_GOVERNOR=1
942         oldIFS="$IFS"
943         IFS="
944 "
945          for line in $(grep FATAL "$LOADCPUFREQ" | sed 's/.*FATAL: //; s/ (.*)//') ; do
946              eerror "$line" ; eend $RC
947          done
948          IFS="$oldIFS"
949       eoutdent
950    elif grep -q done "$LOADCPUFREQ" ; then
951       MODULE=$(grep done "$LOADCPUFREQ" | sed 's/.*done (\(.*\))./\1/')
952       if [ -n "$MODULE" -a "$MODULE" != none ]; then
953          einfo "Loading cpufreq kernel module $MODULE" ; eend 0
954       else
955          SKIP_CPU_GOVERNOR=1
956          ewarn "Could not find an appropriate kernel module for cpu frequency scaling." ; eend 1
957       fi
958    fi
959
960    rm -f $LOADCPUFREQ
961
962    if [ -z "$SKIP_CPU_GOVERNOR" ] ; then
963       einfo "Loading cpufreq_ondemand, setting ondemand governor"
964       RC=0
965       if modprobe cpufreq_ondemand ; RC=$? ; then
966          for file in $(find /sys/devices/system/cpu/ -name scaling_governor 2>/dev/null) ; do
967             echo ondemand > $file
968          done
969       fi
970       eend $RC
971    fi # cpu-governor
972
973    eoutdent
974 fi
975 }
976 # }}}
977
978 # {{{ autostart of ssh
979 config_ssh(){
980 if checkbootparam 'ssh' ; then
981    SSH_PASSWD=''
982    SSH_PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
983    einfo "Bootoption ssh found, trying to set password for user grml."
984    eindent
985    if [ -z "$SSH_PASSWD" ] ; then
986       if [ -x /usr/bin/apg ] ; then
987          SSH_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
988       elif [ -x /usr/bin/gpw ] ; then
989          SSH_PASSWD="$(gpw 1)"
990       elif [ -x /usr/bin/pwgen ] ; then
991          SSH_PASSWD="$(pwgen -1 8)"
992       elif [ -x /usr/bin/hexdump ] ; then
993          SSH_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
994       elif [ -n "$RANDOM" ] ; then
995          SSH_PASSWD="grml${RANDOM}"
996       else
997          SSH_PASSWD=''
998          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
999          eend 1
1000       fi
1001
1002       if [ -n "$SSH_PASSWD" ] ; then
1003          ewarn "No given password for ssh found. Using random password: $SSH_PASSWD" ; eend 0
1004       fi
1005    fi
1006    eoutdent
1007
1008    # finally check if we have a password we can use:
1009    if [ -n "$SSH_PASSWD" ] ; then
1010       # chpasswd sucks, seriously.
1011       if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1012         echo "grml:$SSH_PASSWD" | chpasswd -m
1013       else
1014         echo "grml:$SSH_PASSWD" | chpasswd
1015       fi
1016    fi
1017
1018    einfo 'Starting secure shell server in background.'
1019    /etc/init.d/rmnologin start >>$DEBUG 2>>$DEBUG
1020    /etc/init.d/ssh start >>$DEBUG 2>>$DEBUG &
1021    eend $?
1022
1023    eindent
1024    ewarn 'Warning: please change the password for user grml as soon as possible!'
1025    eoutdent
1026 fi
1027 }
1028 # }}}
1029
1030 # {{{ autostart of x11vnc
1031 config_vnc(){
1032
1033 USER=grml # TODO: make it dynamically configurable
1034 if checkbootparam 'vnc' ; then
1035    VNC_PASSWD=''
1036    VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)"
1037    einfo "Bootoption vnc found, trying to set password for user $USER."
1038    eindent
1039    if [ -z "$VNC_PASSWD" ] ; then
1040       if [ -x /usr/bin/apg ] ; then
1041          VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1042       elif [ -x /usr/bin/gpw ] ; then
1043          VNC_PASSWD="$(gpw 1)"
1044       elif [ -x /usr/bin/pwgen ] ; then
1045          VNC_PASSWD="$(pwgen -1 8)"
1046       elif [ -x /usr/bin/hexdump ] ; then
1047          VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1048       elif [ -n "$RANDOM" ] ; then
1049          VNC_PASSWD="${USER}${RANDOM}"
1050       else
1051          VNC_PASSWD=''
1052          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1053          eend 1
1054       fi
1055
1056       if [ -n "$VNC_PASSWD" ] ; then
1057          ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0
1058       fi
1059    fi
1060    eoutdent
1061
1062    # finally check if we have a password we can use:
1063    if [ -n "$VNC_PASSWD" ] ; then
1064
1065       VNCDIR="/home/${USER}/.vnc"
1066       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1067
1068       if [ ! -x /usr/bin/x11vnc ] ; then
1069          eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package."
1070          eend 1
1071       else
1072          /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $?
1073          /bin/chown -R "$USER": "$VNCDIR"
1074       fi
1075    fi
1076    if checkbootparam 'vnc_connect' ; then
1077       VNC_CONNECT=''
1078       VNC_CONNECT="$(getbootparam 'vnc_connect' 2>>$DEBUG)"
1079       einfo "Bootoption vnc_connect found, will start vnc with connect to $VNC_CONNECT."
1080       #store the options in a file
1081       VNCDIR="/home/${USER}/.vnc"
1082       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1083       echo " --connect $VNC_CONNECT " >> $VNCDIR/options
1084    fi
1085 fi
1086 }
1087 # }}}
1088
1089 # {{{ set password for user grml
1090 config_passwd(){
1091 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1092   einfo "Bootoption passwd found."
1093   PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1094   if [ -n "$PASSWD" ] ; then
1095     echo "grml:$PASSWD" | chpasswd -m ; eend $?
1096   else
1097     eerror "No given password for ssh found. Autostart of SSH will not work." ; eend 1
1098   fi
1099   eindent
1100     ewarn "Warning: please change the password for user grml set via bootparameter as soon as possible!"
1101   eoutdent
1102 fi
1103 }
1104 # }}}
1105
1106 # {{{ Sound
1107 config_mixer () {
1108    if ! [ -x /usr/bin/amixer ] ; then
1109       eerror "amixer binary not available. Can not set sound volumes therefore."
1110       eend 1
1111    else
1112       if ! [ -r /proc/asound/cards ] ; then
1113          ewarn "No soundcard present, skipping mixer settings therefore."
1114          eend 0
1115          return
1116       fi
1117
1118       for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do
1119          einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\""
1120          eindent
1121
1122          if checkbootparam 'vol' ; then
1123             VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1124             if [ -z "$VOL" ] ; then
1125                eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)."
1126                VOL='75'
1127                eend 1
1128             fi
1129          else
1130             VOL='75'
1131          fi
1132
1133          if checkbootparam 'nosound' ; then
1134             einfo "Muting sound devices on request."
1135             ERROR=$(amixer -q set Master mute)
1136             RC=$?
1137             if [ -n "$ERROR" ] ; then
1138                eindent
1139                eerror "Problem muting sound devices: $ERROR"
1140                eoutdent
1141             fi
1142             eend $RC
1143          elif [ -z "$INSTALLED" ] ; then
1144             einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1145
1146             if checkbootparam 'micvol' ; then
1147                MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1148             else
1149                MICVOL=0
1150             fi
1151
1152             for CONTROL in Master PCM ; do
1153                if amixer -q | grep -q "Simple mixer control '$CONTROL'" ; then
1154                   amixer -q set "${CONTROL}" "${VOL}"%
1155                   eend $?
1156                fi
1157             done
1158
1159             if [ ${MICVOL} -ne 0 ] ; then
1160                einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1161                amixer -q set "Mic" $MICVOL &> /dev/null
1162                eend $?
1163             fi
1164          fi # checkbootparam 'nosound'
1165          eoutdent
1166       done
1167    fi
1168 }
1169 # }}}
1170
1171 # {{{ modem detection
1172 config_modem(){
1173 if checkbootparam 'nomodem'; then
1174   ewarn "Skipping check for AC97 modem controller as requested on boot commandline." ; eend 0
1175 else
1176   if [ -x /etc/init.d/sl-modem-daemon ] ; then
1177      if lspci | grep Intel | grep -q "AC'97 Modem Controller" ; then
1178         einfo "AC97 modem controller detected. Start it running 'Start sl-modem-daemon'."
1179         eend 0
1180      fi
1181   fi
1182 fi
1183 }
1184 # }}}
1185
1186 # {{{ wondershaper
1187 config_wondershaper(){
1188  if checkbootparam 'wondershaper' ; then
1189     WONDER="$(getbootparam 'wondershaper' 2>>$DEBUG)"
1190     CMD=wondershaper
1191     DEVICE=""
1192     DOWNSTREAM=""
1193     UPSTREAM=""
1194     if [ -n "$WONDER" ]; then
1195       # Extra options
1196       DEVICE="${WONDER%%,*}"
1197       R="${WONDER#*,}"
1198       if [ -n "$R" -a "$R" != "$WONDER" ]; then
1199         WONDER="$R"
1200         DOWNSTREAM="${WONDER%%,*}"
1201         R="${WONDER#*,}"
1202         if [ -n "$R" -a "$R" != "$WONDER" ]; then
1203           WONDER="$R"
1204           UPSTREAM="${WONDER%%,*}"
1205           R="${WONDER#*,}"
1206         fi
1207       fi
1208     fi
1209     [ -n "$DEVICE" ]     && CMD="$CMD $DEVICE"
1210     [ -n "$DOWNSTREAM" ] && CMD="$CMD $DOWNSTREAM"
1211     [ -n "$UPSTREAM" ]   && CMD="$CMD $UPSTREAM"
1212     einfo "Starting wondershaper (${CMD}) in background."
1213     ( sh -c $CMD & ) && eend 0
1214  fi
1215 }
1216 # }}}
1217
1218 # {{{ syslog-ng
1219 config_syslog(){
1220  if checkbootparam 'nosyslog'; then
1221     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1222  else
1223     SYSLOGD=''
1224     [ -x /etc/init.d/syslog-ng ] && SYSLOGD='syslog-ng'
1225     [ -x /etc/init.d/rsyslog   ] && SYSLOGD='rsyslog'
1226     [ -x /etc/init.d/dsyslog   ] && SYSLOGD='dsyslog'
1227     [ -x /etc/init.d/sysklogd  ] && SYSLOGD='sysklogd'
1228     [ -x /etc/init.d/inetutils-syslogd ] && SYSLOGD='inetutils-syslogd'
1229
1230     if [ -z "$SYSLOGD" ] ; then
1231        eerror "No syslog daemon found." ; eend 1
1232     else
1233        einfo "Starting $SYSLOGD in background."
1234        /etc/init.d/$SYSLOGD start >>$DEBUG &
1235        eend 0
1236     fi
1237  fi
1238 }
1239 # }}}
1240
1241 # {{{ gpm
1242 config_gpm(){
1243  if checkbootparam 'nogpm'; then
1244   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1245  else
1246    if ! [ -r /dev/input/mice ] ; then
1247       eerror "No mouse found - not starting GPM." ; eend 1
1248    else
1249       einfo "Starting gpm in background."
1250       /etc/init.d/gpm start >>$DEBUG &
1251       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start >>$DEBUG ) &
1252       eend 0
1253    fi
1254  fi
1255 }
1256 # }}}
1257
1258 # {{{ services
1259 config_services(){
1260  if checkbootparam 'services' ; then
1261     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1262     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1263     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1264     for service in $(echo -e $SERVICELIST) ; do
1265       # support running (custom) init scripts in non-blocking mode
1266       # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1267       if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1268         einfo "Starting service ${service}."
1269         /etc/init.d/${service} start >>$DEBUG
1270       else
1271         einfo "Starting service ${service} in background."
1272         /etc/init.d/${service} start >>$DEBUG &
1273       fi
1274     done
1275     eend $?
1276  fi
1277 }
1278 # }}}
1279
1280 # {{{ remote files
1281 get_remote_file() {
1282   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1283   SOURCE=$(eval echo "$1")
1284   TARGET="$2"
1285   getconfig() {
1286   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1287        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1288   }
1289   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1290   counter=10
1291   while ! getconfig && [[ "$counter" != 0 ]] ; do
1292     echo -n "Sleeping for 1 second and trying to get config again... "
1293     counter=$(( counter-1 ))
1294     echo "$counter tries left" ; sleep 1
1295   done
1296   if [ -s "$TARGET" ] ; then
1297     einfo "Downloading was successfull." ; eend 0
1298     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1299     md5sum ${TARGET} ; eend 0
1300     return 0;
1301   else
1302     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1303     return 1;
1304  fi
1305 }
1306 # }}}
1307
1308 # {{{ config files
1309 config_netconfig(){
1310  if checkbootparam 'netconfig' ; then
1311   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1312   CONFIGFILE='/tmp/netconfig.grml'
1313
1314   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1315     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1316   fi
1317
1318  fi
1319 }
1320 # }}}
1321
1322 # {{{ remote scripts
1323 config_netscript() {
1324  if checkbootparam 'netscript' ; then
1325   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1326   SCRIPTFILE='/tmp/netscript.grml'
1327
1328   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1329     chmod +x ${SCRIPTFILE}
1330     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1331   fi
1332
1333  fi
1334 }
1335 # }}}
1336
1337 # {{{ stats
1338 config_stats() {
1339  if ! checkbootparam 'nostats' ; then
1340    BASE_URL="http://stats.grml.org/report/"
1341    ACTION_NAME=Boot
1342
1343    HOST_ID=$(cat /proc/sys/kernel/random/boot_id)
1344
1345    grep -q " lm " /proc/cpuinfo && HAS_64BIT="1" || HAS_64BIT="0"
1346    DATE_STRING=$(date +'h=%H&m=%M&s=%S')
1347    [ -e /etc/grml_version ] && VERSION=$(cat /etc/grml_version) || \
1348      VERSION=$(lsb_release -d | awk -F: '{gsub(/^[ \t]+/, "", $2); print $2}')
1349
1350    PARAMS="$( echo "$CMDLINE" | sed -e 's/=[^ ]*/=VALUE/g' | tr " " "\n"|sort|tr "\n" " " )"
1351
1352    echo "$CMDLINE" | grep -q -e "fetch|nfsroot" && BOOT="remote"
1353    [ -z "$BOOT" ] && BOOT="local"
1354
1355    ADDITIONAL_PARAMS=""
1356    ( [ -n "$COLUMNS" ] && [ -n "$LINES" ] ) && \
1357      ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS&res=$((COLUMNS * 8))x$((LINES * 16))"
1358
1359    URI='$BASE_URL?action=${ACTION_NAME}\&$DATE_STRING\&unique_id=${HOST_ID}\&support_64bit=$HAS_64BIT\&version=$version\&bootup=$BOOT\&params=$PARAMS$ADDITIONAL_PARAMS'
1360
1361    get_remote_file "$URI" "/dev/null"  >/dev/null 2>&1 &!
1362  fi
1363 }
1364 # }}}
1365 # {{{ fix/workaround for unionfs
1366 fix_unionfs(){
1367   if [ -z "$INSTALLED" ]; then
1368    touch /var/cache/apt/*cache.bin
1369   fi
1370 }
1371 # }}}
1372
1373 # {{{ start X window system via grml-x
1374 config_x_startup(){
1375 # make sure we start X only if startx is used *before* a nostartx option
1376 # so it's possible to disable automatic X startup using nostart
1377 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1378  if [ -x "$(which X)" ] ; then
1379   if [ -z "$INSTALLED" ] ; then
1380    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1381    if [ -z "$WINDOWMANAGER" ] ; then
1382      einfo "No window manager specified. Taking ${WHITE}wm-ng${NORMAL} as default." && eend 0
1383      WINDOWMANAGER="wm-ng"
1384    else
1385      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1386    fi
1387    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1388    config_userfstab || fstabuser='grml'
1389  cat>|/etc/init.d/xstartup<<EOF
1390 #!/bin/sh
1391 su $fstabuser -c "/usr/bin/grml-x $WINDOWMANAGER"
1392 EOF
1393    chmod 755 /etc/init.d/xstartup
1394
1395    # adjust inittab for xstartup
1396    if grep -q '^6:' /etc/inittab ; then
1397       sed -i 's|^6:.*|6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/share/grml-scripts/run-welcome" >/dev/tty6 2>\&1 </dev/tty6|' /etc/inittab
1398    else # just append tty6 to inittab if no definition is present:
1399       echo '6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/share/grml-scripts/run-welcome" >/dev/tty6 2>&1 < /dev/tty6' >> /etc/inittab
1400    fi
1401
1402    /sbin/telinit q ; eend $?
1403
1404    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1405       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1406    else
1407       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1408    fi
1409
1410   else
1411     eerror "We are not running in live mode - startx will not work, skipping it."
1412     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1413   fi
1414  else
1415    eerror "/usr/bin/X is not present on this grml flavour."
1416    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1417  fi
1418 fi
1419 }
1420 # }}}
1421
1422 # {{{ configuration framework
1423 config_extract(){
1424 if checkbootparam 'extract' ; then
1425  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1426  EXTRACTOPTIONS="-- -x $EXTRACT"
1427 fi
1428 }
1429
1430 config_finddcsdir() {
1431 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1432 #    on the command line, nothing is changed and the dcs files are
1433 #    searched within the .iso, $dcs-dir is set to the root directory
1434 #    within the .iso
1435 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1436 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1437 #    set, $dcs-dir is set to the root directory within the .iso.
1438 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1439 #    foo, even if a GRMLCFG partition is present.
1440 DCSDIR=""
1441 DCSMP="/mnt/grml"
1442 # autoconfig, see issue673
1443 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1444 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1445 if checkbootparam 'noautoconfig' || checkbootparam 'forensic' ; then
1446   ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1447 else
1448   if [ -z "$INSTALLED" ] ; then
1449     if checkbootparam 'myconfig' ; then
1450       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1451       if [ -z "$DCSDEVICE" ]; then
1452         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1453       fi # [ -z "$DCSDEVICE" ]
1454     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1455       einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1456       eindent
1457       # We do need the following fix so floppy disk is available to blkid in any case :-/
1458       if [ -r /dev/fd0 ] ; then
1459         einfo "Floppy device detected. Trying to access floppy disk."
1460         if timeout 4 dd if=/dev/fd0 of=/dev/null bs=512 count=1 >>$DEBUG 2>&1 ; then
1461            blkid /dev/fd0 >>$DEBUG 2>&1
1462         fi
1463       fi
1464       DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1465       if [ -n "$DCSDEVICE" ]; then
1466         DCSMP="/mnt/grmlcfg"
1467       fi
1468       eoutdent
1469     fi
1470
1471     # if not specified/present then assume default:
1472     if [ -z "$DCSDEVICE" ]; then
1473       DCSDIR="/live/image"
1474     else
1475       eindent
1476       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1477       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1478       if [ -n "$DCSDIR" ]; then
1479         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1480       else
1481         [ -d $DCSMP ] || mkdir $DCSMP
1482         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1483         mount -o ro -t auto $DCSDEVICE  $DCSMP ; RC="$?"
1484         if [[ $RC == 0 ]]; then
1485           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1486         else
1487           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1488         fi
1489         DCSDIR="$DCSMP"
1490       fi
1491       eoutdent
1492     fi
1493   fi
1494 fi
1495
1496 if [ -n "$DCSDIR" -a "$DCSDIR" != "/live/image" ] ; then
1497   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1498 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1499   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1500 fi
1501 }
1502
1503
1504 config_partconf() {
1505 if checkbootparam 'partconf' ; then
1506  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1507  if [ -n "$MOUNTDEVICE" ]; then
1508    [ -d /mnt/grml ] || mkdir /mnt/grml
1509    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1510     if [[ $RC == 0 ]]; then
1511       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1512       einfo "Copying files from $MOUNTDEVICE over grml system."
1513       for file in `cat /etc/grml/partconf` ; do
1514         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1515         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1516       done && eend 0
1517     else
1518       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1519     fi # mount $MOUNTDEVICE
1520    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1521  else
1522    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1523  fi # [ -n "$MOUNTDEVICE" ]
1524 fi
1525 }
1526 # }}}
1527
1528 # {{{ /cdrom/.*-options
1529 config_debs(){
1530 if checkbootparam 'debs' ; then
1531    iszsh && setopt localoptions shwordsplit
1532    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1533    if [ -z "$DEBS" ] ; then
1534       DEBS="*.deb"
1535    fi
1536    if ! echo $DEBS | grep -q '/'; then
1537      # backwards compatibility: if no path is given get debs from debs/
1538      DEBS="debs/$DEBS"
1539    fi
1540    einfo "Tring to install debian package(s) ${DEBS}"
1541    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1542    dpkg -i $DEBS ; eend $?
1543 fi
1544 }
1545
1546 config_scripts(){
1547 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1548    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1549    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1550      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1551    fi
1552    if ! echo $SCRIPTS | grep -q '/'; then
1553      # backwards compatibility: if no path is given get scripts from scripts/
1554      SCRIPTS="scripts/$SCRIPTS"
1555    fi
1556    if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1557      # we are executing from a GRMLCFG labeled fs
1558      # kick everything we have done before and start over
1559      SCRIPTS="$(cd ${DCSDIR}; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1560    fi
1561    if [ -n "$SCRIPTS" ]; then
1562      SCRIPTS="${DCSDIR}/$SCRIPTS"
1563      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1564        einfo "Trying to execute ${SCRIPTS}"
1565        sh -c $SCRIPTS
1566      elif [ -d "$SCRIPTS" ]; then
1567        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1568        run-parts $SCRIPTS
1569      else
1570        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1571        sh -c $SCRIPTS
1572      fi
1573    fi
1574 fi
1575 }
1576
1577 config_config(){
1578 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1579   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1580   if [ -z "$CONFIG" ]; then
1581     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1582   fi
1583   if [ -n "$CONFIG" ]; then
1584     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1585       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1586
1587       cp -a ${DCSDIR}/${CONFIG}/* /
1588     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1589       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1590
1591       cd /
1592       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1593     else
1594       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1595     fi
1596   fi
1597 fi
1598 }
1599 # }}}
1600
1601 # {{{ confing_umount_dcsdir
1602 config_umount_dcsdir(){
1603    # umount $DCSMP if it was mounted by finddcsdir
1604    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1605 }
1606 # }}}
1607
1608 # {{{ mypath
1609 config_mypath(){
1610 if checkbootparam 'mypath' ; then
1611    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1612    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1613    touch /etc/grml/my_path
1614    chmod 644 /etc/grml/my_path
1615    # make sure the directories exist:
1616    eindent
1617    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1618        if ! [ -d "$i" ] ; then
1619           einfo "Creating directory $i"
1620           mkdir -p "$i" ; eend $?
1621        fi
1622    done
1623    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1624    eoutdent
1625 fi
1626 }
1627 # }}}
1628
1629 # {{{ distcc
1630 config_distcc(){
1631 if checkbootparam 'distcc' ; then
1632  OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)"
1633  if [ -n "$OPTIONS" ]; then
1634     NET=""
1635     INTERFACE=""
1636     if [ -n "$OPTIONS" ]; then
1637       NET="${OPTIONS%%,*}"
1638       R="${OPTIONS#*,}"
1639       if [ -n "$R" -a "$R" != "$OPTIONS" ]; then
1640         OPTIONS="$R"
1641         INTERFACE="${OPTIONS%%,*}"
1642         R="${OPTIONS#*,}"
1643       fi
1644     fi
1645  fi
1646  CONFIG=/etc/default/distcc
1647  sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#"  $CONFIG
1648  sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG
1649
1650  if [ -n "$INTERFACE" ] ; then
1651    IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1652
1653    counter=10
1654    while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do
1655      counter=$(( counter-1 ))
1656      ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left."
1657      sleep 3
1658      IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}')
1659    done
1660  fi
1661
1662  if [ -n "$IP" ] ; then
1663    sed -i "s#^LISTENER=.*#LISTENER=$IP#"      $CONFIG
1664
1665    einfo "Bootoption distcc found. Preparing setup for distcc daemon."
1666    eindent
1667     id distccd >/dev/null 2>&1 || \
1668     (
1669       einfo "Creating distcc user" ; \
1670       adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $?
1671     )
1672
1673     einfo "Starting distcc for network ${NET}, listening on ${IP}."
1674    /etc/init.d/distcc start >/dev/null ; eend $?
1675    eoutdent
1676  else
1677    eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1
1678  fi
1679 fi
1680
1681 if checkbootparam 'gcc'; then
1682  GCC="$(getbootparam 'gcc' 2>>$DEBUG)"
1683  eindent
1684  einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}."
1685  eoutdent
1686  rm -f /usr/bin/gcc
1687  ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $?
1688 fi
1689
1690 if checkbootparam 'gpp'; then
1691  GPP="$(getbootparam 'gpp' 2>>$DEBUG)"
1692  eindent
1693   einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}."
1694   if [ -x /usr/bin/g++-${GPP} ] ; then
1695      rm -f /usr/bin/g++
1696      ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $?
1697   fi
1698   einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}."
1699   if [ -x /usr/bin/cpp-${GPP} ] ; then
1700      rm -f /usr/bin/cpp
1701      ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $?
1702   fi
1703  eoutdent
1704 fi
1705
1706 }
1707 # }}}
1708
1709 # {{{ load modules
1710 # Notice: use it only on live-cd system, if running from harddisk please
1711 # add modules to /etc/modules and activate /etc/init.d/module-init-tools
1712 # in /etc/runlevel.conf
1713 config_modules(){
1714 MODULES_FILE=/etc/grml/modules
1715 if checkbootparam 'nomodules' ; then
1716   ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0
1717 elif [ -z "$INSTALLED" ]; then
1718  if [ -r $MODULES_FILE ] ; then
1719   einfo "Loading modules specified in ${MODULES_FILE}:"
1720   eindent
1721   grep '^[^#]' $MODULES_FILE | \
1722   while read module args; do
1723     [ "$module" ] || continue
1724       einfo "${module}"
1725       modprobe $module $args ; eend $?
1726   done
1727   eoutdent
1728  else
1729   ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1
1730  fi
1731 fi
1732 }
1733 # }}}
1734
1735 # {{{ SW-RAID
1736 config_swraid(){
1737   [ -n "$INSTALLED" ] && return 0
1738
1739   # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption
1740   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1741      checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then
1742      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1743   else
1744     [ -e /proc/mdstat ] || modprobe md_mod
1745     if ! [ -x /sbin/mdadm ] ; then
1746        eerror "mdadm not available, can not execute it." ; eend 1
1747     else
1748
1749        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1750        # find out whether we have a valid configuration file already
1751        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1752           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1753           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1754           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1755         else
1756           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1757        fi
1758
1759        if ! checkbootparam 'swraid' ; then
1760           eindent
1761           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1762           eoutdent
1763        else
1764           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1765           eindent
1766            IFSOLD=${IFS:-}
1767            IFS='
1768 '
1769            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
1770                case $line in
1771                  *'No arrays found'*)
1772                    ewarn "$line" ; eend 0
1773                    ;;
1774                  *)
1775                    einfo "$line" ; eend 0
1776                    ;;
1777                esac
1778            done
1779            IFS=$IFSOLD
1780          eoutdent
1781
1782          if [ -r /proc/mdstat ] ; then
1783             eindent
1784             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1785             if [ -z "$MDSTAT" ] ; then
1786                ewarn "No active arrays found" ; eend 0
1787             else
1788                IFSOLD=${IFS:-}
1789                IFS='
1790 '
1791                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1792                    einfo "active arrays: $line" ; eend 0
1793                done
1794                IFS=$IFSOLD
1795             fi
1796             eoutdent
1797          fi # /proc/mdstat
1798        fi # bootoption swraid
1799
1800      fi # is /sbin/mdadm executable?
1801   fi # check for bootoptions
1802 }
1803 # }}}
1804
1805 # {{{ dmraid
1806 config_dmraid(){
1807   [ -n "$INSTALLED" ] && return 0
1808
1809   if checkbootparam 'nodmraid' ; then
1810     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1811     return 0
1812   fi
1813
1814   if ! [ -x /sbin/dmraid ] ; then
1815     eerror "dmraid not available, can not execute it." ; eend 1
1816     return
1817   fi
1818
1819   dmraid_wrapper() {
1820     # usage: dmraid_wrapper <dmraid_option>
1821     [ -n "$1" ] || return 1
1822
1823     IFSOLD=${IFS:-}
1824     IFS='
1825 '
1826     eindent
1827
1828     for line in $(dmraid $1 ; echo errcode:$?); do
1829       case $line in
1830         *'no block devices found'*)
1831           einfo "No block devices found" ; eend 0
1832           break
1833           ;;
1834         *'no raid disks'*)
1835           einfo "No active dmraid devices found" ; eend 0
1836           break
1837           ;;
1838         errcode:0)
1839           eend 0;
1840           ;;
1841         errcode:1)
1842           eend 1
1843           ;;
1844         *)
1845           einfo "$line"
1846           ;;
1847       esac
1848     done
1849
1850     eoutdent
1851     IFS=$IFSOLD
1852   }
1853
1854   if checkbootparam 'dmraid' ; then
1855     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1856     if [ "$ACTION" = "off" ] ; then
1857       # Deactivates all active software RAID sets:
1858       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1859       dmraid_wrapper -an
1860     else
1861       # Activate all software RAID sets discovered:
1862       einfo "Activating present dmraid sets (as requested via dmraid):"
1863       dmraid_wrapper -ay
1864     fi
1865
1866     return
1867   fi
1868
1869   # by default (no special bootoptions) discover all software RAID devices:
1870   einfo "Searching for any present dmraid sets:"
1871   dmraid_wrapper -r
1872 }
1873 # }}}
1874
1875 # {{{ LVM (Logical Volumes)
1876 config_lvm(){
1877   [ -n "$INSTALLED" ] && return 0
1878
1879   if checkbootparam 'nolvm' ; then
1880      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1881   else
1882     # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2
1883     if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/lvm ] ; then
1884        eerror "LVM not available, can not execute it." ; eend 1
1885     else
1886        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1887           einfo "You seem to have logical volumes (LVM) on your system."
1888           eindent
1889           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1890           eend 0
1891           if checkbootparam 'lvm' ; then
1892              einfo "Bootoption LVM found. Searching for logical volumes:"
1893              /etc/init.d/lvm2 start ; eend $?
1894           fi
1895           eoutdent
1896        fi
1897     fi # check for lvm binary
1898   fi # check for bootoption nolvm
1899 }
1900 # }}}
1901
1902 # {{{ debnet: setup network based on an existing one found on a partition
1903 config_debnet(){
1904 if checkbootparam 'debnet' ; then
1905  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1906  /usr/sbin/debnet
1907 fi
1908 }
1909 # }}}
1910
1911 # {{{ disable console blanking
1912 config_blanking(){
1913 if checkbootparam 'noblank' ; then
1914   einfo "Bootoption noblank found. Disabling monitor blanking."
1915   setterm -blank 0 ; eend $?
1916 fi
1917 }
1918 # }}}
1919
1920 # {{{ tohd= bootoption
1921 config_tohd()
1922 {
1923   if checkbootparam 'tohd' ; then
1924      local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)"
1925      if [ -z "$TARGET" ] ; then
1926         eerror "Error: tohd specified without any partition, can not continue." ; eend 1
1927         eerror "Please use something like tohd=/dev/sda9." ; eend 1
1928         return 1
1929      fi
1930
1931      if ! [ -b "$TARGET" ] ; then
1932         eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1
1933         return 1
1934      fi
1935
1936      if grep -q $TARGET /proc/mounts ; then
1937         eerror "$TARGET already mounted, skipping execution of tohd therefore."
1938         eend 1
1939         return 1
1940      fi
1941
1942      local MOUNTDIR=$(mktemp -d)
1943
1944      if mount -o rw "$TARGET" "$MOUNTDIR" ; then
1945         einfo "Copyring live system to $TARGET - this might take a while"
1946         rsync -a --progress /live/image/live $MOUNTDIR
1947         sync
1948         umount "$MOUNTDIR"
1949         eend $?
1950         einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0
1951      else
1952         eerror "Error when trying to mount $TARGET, sorry."; eend 1
1953         return 1
1954      fi
1955
1956      rmdir "$MOUNTDIR"
1957   fi
1958 }
1959 # }}}
1960
1961 # {{{ debootstrap: automatic installation
1962 config_debootstrap(){
1963
1964 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
1965
1966 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
1967
1968 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
1969    eindent
1970    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
1971    eoutdent
1972    exit 1
1973 fi
1974
1975 if checkbootparam 'target' ; then
1976   TARGET=''
1977   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
1978   # notice: the following checks whether the given partition is available, if not the skip
1979   # execution of grml-debootstrap as it might result in data loss...
1980   if ! [ -r "$TARGET" ] ; then
1981      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
1982   fi
1983 else
1984   eindent
1985   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
1986   eoutdent
1987   exit 1
1988 fi
1989
1990 if checkbootparam 'grub' ; then
1991   GRUB=''
1992   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
1993 fi
1994
1995 if checkbootparam 'groot' ; then
1996   GROOT=''
1997   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
1998 fi
1999
2000 if checkbootparam 'release' ; then
2001   RELEASE=''
2002   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
2003 fi
2004
2005 if checkbootparam 'mirror' ; then
2006   MIRROR=''
2007   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
2008 fi
2009
2010 if checkbootparam 'boot_append' ; then
2011   BOOT_APPEND=''
2012   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
2013 fi
2014
2015 if checkbootparam 'password' ; then
2016   PASSWORD=''
2017   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
2018 fi
2019
2020 # now check which options are available
2021 if [ -n "TARGET" ] ; then
2022    TARGETCMD="--target $TARGET"
2023 else
2024    TARGETCMD=''
2025    eindent
2026    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
2027    eoutdent
2028    exit 1
2029 fi
2030 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
2031 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
2032 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
2033 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
2034 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
2035 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
2036
2037 # and finally write script and execute it
2038 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
2039 #!/bin/sh
2040 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
2041 EOF
2042
2043 chmod 750  /usr/bin/grml-debootstrap_noninteractive
2044
2045 screen /usr/bin/grml-debootstrap_noninteractive
2046 einfo "Invoking a shell, just exit to continue booting..."
2047 /bin/zsh
2048
2049 fi # checkbootparam "BOOT_IMAGE=debian2hd
2050 }
2051 # }}}
2052
2053 config_virtualbox_shared_folders() {
2054 if [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then
2055   einfo "VirtualBox detected, trying to set up Shared Folders."
2056   if ! modprobe -l | grep -q vboxsf.ko ; then
2057     ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
2058     eend 0
2059   elif ! [ -x /usr/sbin/VBoxService ] ; then
2060     ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
2061     eend 0
2062   else
2063     eindent
2064
2065       einfo "Loading vboxsf driver."
2066       lsmod | grep -q vboxsf || modprobe vboxsf
2067       eend $?
2068
2069       einfo "Adjusting /dev/vboxguest."
2070       chown root:vboxsf /dev/vboxguest
2071       chmod 660 /dev/vboxguest
2072       eend $?
2073
2074       if [ -n "$CONFIG_FSTAB_USER" ] ; then
2075         fstabuser="$CONFIG_FSTAB_USER"
2076       else
2077         fstabuser=$(getent passwd 1000 | cut -d: -f1)
2078       fi
2079       einfo "Adding $fstabuser to group vboxsf."
2080       adduser grml vboxsf &>/dev/null
2081       eend $?
2082
2083       einfo "Starting VBoxService."
2084       VBoxService >/dev/null &
2085       eend $?
2086
2087     eoutdent
2088   fi
2089 fi
2090 }
2091
2092 # {{{ Support customization
2093 config_distri(){
2094 if checkbootparam 'distri'; then
2095   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
2096   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
2097      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
2098      # make sure the desktop.jpg file is not a symlink, so copying does not file then
2099      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
2100      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
2101   fi
2102 fi
2103 }
2104 # }}}
2105
2106 ## END OF FILE #################################################################
2107 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=3