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