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