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