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