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