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