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