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