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