diff options
author | Willy Tarreau <w@1wt.eu> | 2006-07-16 15:09:50 +0200 |
---|---|---|
committer | Willy Tarreau <willy@wtap.(none)> | 2006-07-26 12:03:29 +0200 |
commit | 8ddae1eaf26ea45af09b36c397ca32797291a6c4 (patch) | |
tree | a724bd8f46f8228abb7e1d4f29006dd21acd08b1 | |
parent | [RELEASE] init-scripts-0.3.14 (diff) | |
download | init-scripts-8ddae1eaf26ea45af09b36c397ca32797291a6c4.tar.gz |
[RELEASE] init-scripts-0.3.15v0.3.15
-rw-r--r-- | .flxfiles | 28 | ||||
-rwxr-xr-x | .preinit | 68 | ||||
-rw-r--r-- | ChangeLog | 49 | ||||
-rw-r--r-- | TODO | 3 | ||||
l--------- | etc/initscript | 1 | ||||
-rwxr-xr-x | etc/startup.rc | 20 | ||||
-rwxr-xr-x | obsolete/syslog-ng | 33 | ||||
-rwxr-xr-x | sbin/init.d/crond | 21 | ||||
-rwxr-xr-x | sbin/init.d/echelogd | 187 | ||||
-rwxr-xr-x | sbin/init.d/firewall | 212 | ||||
-rwxr-xr-x | sbin/init.d/functions | 906 | ||||
-rwxr-xr-x | sbin/init.d/keyboard | 18 | ||||
-rwxr-xr-x | sbin/init.d/klogd | 11 | ||||
-rwxr-xr-x | sbin/init.d/logrotate | 16 | ||||
-rwxr-xr-x | sbin/init.d/monitor | 46 | ||||
-rwxr-xr-x | sbin/init.d/mouse | 23 | ||||
-rwxr-xr-x | sbin/init.d/network | 457 | ||||
-rwxr-xr-x | sbin/init.d/ntp | 56 | ||||
-rwxr-xr-x | sbin/init.d/pdnsd | 16 | ||||
-rwxr-xr-x | sbin/init.d/squid | 43 | ||||
-rwxr-xr-x | sbin/init.d/sshd | 103 | ||||
-rwxr-xr-x | sbin/init.d/stat | 105 | ||||
-rwxr-xr-x | sbin/init.d/sysprofiles | 3 | ||||
-rwxr-xr-x | sbin/init.d/system | 76 | ||||
-rwxr-xr-x | sbin/init.d/thttpd | 27 | ||||
-rwxr-xr-x | sbin/initscript | 10 | ||||
-rwxr-xr-x | sbin/rc.0 | 83 | ||||
l--------- | sbin/rc.6 | 1 | ||||
-rwxr-xr-x | sbin/rc.K | 41 | ||||
-rwxr-xr-x | sbin/rc.M | 70 | ||||
-rwxr-xr-x | sbin/rc.S | 178 |
31 files changed, 2911 insertions, 0 deletions
diff --git a/.flxfiles b/.flxfiles new file mode 100644 index 0000000..c4d075b --- /dev/null +++ b/.flxfiles @@ -0,0 +1,28 @@ +sbin/init.d +sbin/init.d/echelogd +sbin/init.d/firewall +sbin/init.d/functions +sbin/init.d/keyboard +sbin/init.d/klogd +sbin/init.d/monitor +sbin/init.d/mouse +sbin/init.d/network +sbin/init.d/ntp +sbin/init.d/squid +sbin/init.d/sshd +sbin/init.d/stat +sbin/init.d/sysprofiles +sbin/init.d/system +sbin/init.d/thttpd +sbin/init.d/pdnsd +sbin/init.d/crond +sbin/init.d/logrotate +sbin/rc.0 +sbin/rc.6 +sbin/rc.K +sbin/rc.M +sbin/rc.S +sbin/initscript +etc/initscript +etc/startup.rc +.preinit diff --git a/.preinit b/.preinit new file mode 100755 index 0000000..8936720 --- /dev/null +++ b/.preinit @@ -0,0 +1,68 @@ +#!/sbin/init < +# This .preinit is to be copied onto a hard disk to be used as-is. +# Don't forget to change the links at the bottom ! +# +# mem, kmem, null, zero, random, urandom, tty0, tty, console, ptmx, initctl +# full, fd +mt /proc /proc proc rw + +# if we need /tmp now, let's first try to mount /tmp as a tmpfs, next /var if it fails. +# mt /tmp /tmp tmpfs rw +# |mt /var /var tmpfs rw mode=755 +# md /var/tmp 1777 +# md /var/run 755 +md /dev/pts 755 + +bl 0600 0 0 3 0 hd[c,ab,64][I,0-16,1] +bl 0600 0 0 22 0 hd[c,cd,64][I,0-16,1] +bl 0600 0 0 33 0 hd[c,ef,64][I,0-16,1] +bl 0600 0 0 8 0 sd[c,a-h,16][I,0-15,1] +md /dev/rd 755 # DAC960 raid disks (majors 48-55) +bl 0600 0 0 48 0 rd/c0d[i,0-31,8] +bl 0600 0 0 48 1 rd/c0d[i,0-31,8]p[i,1-7,1] +md /dev/ida 755 # Compaq raid disks (majors 72-79) +bl 0600 0 0 72 0 ida/c0d[i,0-15,16] +bl 0600 0 0 72 1 ida/c0d[i,0-15,16]p[i,1-15,1] +md /dev/cciss 755 # Compaq CCISS raid disks (major 104) +bl 0600 0 0 104 0 cciss/c0d[i,0-15,16] +bl 0600 0 0 104 1 cciss/c0d[i,0-15,16]p[i,1-15,1] +bl 0600 0 0 11 0 sr[i,0-16,1] +ch 0600 0 0 9 0 st[i,0-15,1] +bl 0600 0 0 9 0 md[i,0-15,1] +bl 0600 0 0 2 0 fd0 +bl 0600 0 0 2 28 fd0u1440 +ch 0600 0 5 2 0 pty[c,p-za-f,16][h,0-f,1] +ch 0600 0 5 3 0 tty[c,p-za-f,16][h,0-f,1] +ch 0600 0 5 4 1 tty[i,1-12,1] +bl 0600 0 0 7 0 loop[i,0-9,1] +bl 0600 0 0 1 0 ram[i,0-9,1] +ch 0600 0 5 4 64 ttyS[i,0-9,1] +ch 0600 0 0 108 0 ppp +ch 0600 0 3 10 1 psaux +ch 0600 0 0 10 144 nvram +ch 0600 0 0 10 130 watchdog +ch 0600 0 0 10 135 rtc +ch 0600 0 0 10 156 lcd +ch 0600 0 0 10 185 keypad +ch 0600 0 0 10 186 smartcard +bl 0400 0 0 1 250 initrd +ch 0600 0 0 14 0 mixer +ch 0600 0 0 14 3 dsp +md /dev/input 755 +ch 0600 0 0 13 63 input/mice + +ln psaux /dev/mouse +ln hdc /dev/cdrom + +md /dev/fs 755 + +# The partitions may be referenced here, so that +# lilo.conf and fstab only use links. +ln hda /dev/mbr +ln hda1 /dev/boot +ln hda2 /dev/swap +ln hda3 /dev/root +ln ../hda6 /dev/fs/var + +in /sbin/init-sysv + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..93284b2 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,49 @@ +2003/06/19 +- correction d'un bug dans functions : lors de l'évaluation d'un service, + toutes les options des autres services n'étaient pas invalidées, ce qui + posait des problèmes pour certaines commandes (ex: modprobe) +- appel de la fonction "do_help" si une action est inconnue +- ajout du script firewall +- ajout des paramètres speed,duplex,auto à network, et support de ethtool +- release de la 0.3.15 qui corrige les bugs introduits dans la 0.3.14 ! +2003/06/17 +- déplacement de /sbin/init.d/syslog-ng vers le package syslog-ng +- création de /var/log en root:log:2750 +2003/06/16 +- ajout de la fonction 'daemon' qui permet de lancer un processus + détaché de ses file-descripteurs, du tty et du process père. +- cron utilise désormais daemon sinon une machine démarrant cron ne + peut pas finir de s'initialiser car il ne ferme pas ses fd avant le + fork ! +2003/06/12 +- correction de la lecture du pid dans functions +- valueof ne fait le grep que si le fichier existe +- correctifs sur le script ntp +2003/06/05 +- petits correctifs et quelques mises à jour +- plusieurs scripts comprennent dorénavant l'option nice +- script squid +- droits un peu moins restrictifs sur certains fichiers +2003/02/18 +- création de /var/state (utilisé par dhcp par exemple) +- correction de mouse : utilise /usr/sbin/gpm et redirige std* vers /dev/null +- functions : do_stop_with_pidfile supprime les fichiers de pid restants (gpm...) +- rc.M : cesse de lancer cron et atd, ce n'est pas à lui de le faire. +- rectification de rc.S : bash ne teste pas l'état R/W des filesystems, donc on + crée des fichiers temporaires. De plus, tentative coûte que coûte de créer /tmp. +- dans rc.S, en cas d'erreur, on remonte tout en R/O au lieu du sulogin qui stoppe + le démarrage du système. +- correction des droits de /var dans /.preinit + ajout de quelques entrées +2003/02/09: +- on peut maintenant lancer des services même si la section n'existe pas dans + config.rc +- sbin/init.d/system utilise désormais /proc pour positionner hostname et domainname. +2003/01/26: echelog +- lecture du fichier de configuration de echelog, déduction des sous fichiers + de configuration et des répertoires de spool +- do_stop spécifique +20030115-b : +- ntp: option keys à utiliser sous la forme opt_keys dans cmdline +- ntp: positonnel procname à ntpd +* echelogd: traiter l'impossibilité d'ouverture pour cause de mauvais + positionnement dans le cache du Sender/Receiver @@ -0,0 +1,3 @@ +- prendre en compte l'option nice en global +- ajouter une option chroot globale si c'est possible +- ajouter les options 'chain' et 'need' en global diff --git a/etc/initscript b/etc/initscript new file mode 120000 index 0000000..5193c03 --- /dev/null +++ b/etc/initscript @@ -0,0 +1 @@ +../sbin/initscript
\ No newline at end of file diff --git a/etc/startup.rc b/etc/startup.rc new file mode 100755 index 0000000..c41dbe5 --- /dev/null +++ b/etc/startup.rc @@ -0,0 +1,20 @@ +#!/bin/sh + +/sbin/init.d/sysprofiles /etc/config.rc + +#echo 1 > /proc/sys/net/ipv4/ip_forward +#/sbin/init.d/network restart lo +#/sbin/modprobe softdog 15 +#/sbin/modprobe button +#/sbin/modprobe i2c-viapro +#/sbin/modprobe i2c-isa +#/sbin/modprobe via686a +#/sbin/modprobe eeprom +#/sbin/modprobe via82cxxx_audio +#/sbin/modprobe usb-uhci +#/sbin/modprobe usb-storage +#/sbin/modprobe sd_mod +##/sbin/modprobe hid +##/sbin/modprobe mousedev +##/sbin/modprobe keybdev + diff --git a/obsolete/syslog-ng b/obsolete/syslog-ng new file mode 100755 index 0000000..bfe45d6 --- /dev/null +++ b/obsolete/syslog-ng @@ -0,0 +1,33 @@ +#!/bin/bash + +. `dirname $0`/functions + +option config standard_option /etc/syslog-ng/syslog-ng.conf +option nice standard_option 0 +option chain standard_option +option pidfile reserved_option /var/run/syslog-ng.pid + +option bin reserved_option /sbin/syslog-ng +option cmdline reserved_option 'nice -n $opt_nice $bin -f $opt_config -p $pidfile' + +# we might want to start klogd right after syslog-ng +function fct_post_start { + if [ -n "$opt_chain" ]; then + /sbin/init.d/$opt_chain start >/dev/null 2>&1 || echo "Error starting $opt_chain." + fi +} + +function fct_pre_stop { + if [ -n "$opt_chain" ]; then + /sbin/init.d/$opt_chain stop >/dev/null 2>&1 || echo "Error stopping $opt_chain." + fi +} + +function do_update { + if [ -e $pidfile ] ; then + read < $pidfile + [ "$REPLY" ] && kill -HUP $REPLY > /dev/null 2>&1 + fi +} + +load_config diff --git a/sbin/init.d/crond b/sbin/init.d/crond new file mode 100755 index 0000000..98724c6 --- /dev/null +++ b/sbin/init.d/crond @@ -0,0 +1,21 @@ +#!/bin/bash + +# warning : crond is buggy, it doesn't close its fd's before forking ! + +. `dirname $0`/functions + +option bin reserved_option /usr/sbin/crond +option cmdline reserved_option 'daemon $bin' + +pidfile=/var/run/cron.pid +crontab=/etc/crontab +crontabdir=/var/spool/cron + +function fct_pre_start { + if [ ! -d $crontabdir] ; then + mkdir -p -m 750 $crontabdir || return 1 + fi +} + +load_config + diff --git a/sbin/init.d/echelogd b/sbin/init.d/echelogd new file mode 100755 index 0000000..e4eada7 --- /dev/null +++ b/sbin/init.d/echelogd @@ -0,0 +1,187 @@ +#!/bin/bash + +. `dirname $0`/functions + +option bin reserved_option /opt/echelog/sbin/echelogd +option config standard_option /etc/echelog/echelog.conf +option runas standard_option echelogc:daemon +option cmdline reserved_option '$bin -C $opt_config' +#option check_interval reserved_option 60 + +# assign default values to options and variables before parsing the cfg file +function fct_pre_start { + local path=$( dirname $opt_config ) + local file + + if [ ! -r $opt_config ] ; then + echo "Can't read configuration file '$opt_config'." + exit 1 + fi + while read ; do + set -- $REPLY + if [ "$1" = Module ] ; then + # build all directories + for file in $( grep -i "^\(SpoolDir\|StateDir\)" $path/$(eval echo $4) \ + | awk '{print $2}' ) ; do + if [ -d "$file" ] ; then : + elif [ -L "$file" -a -d "$( readlink $file )" ] ; then : + elif [ -e "$file" ] ; then + echo "Wished directory '$file' isn't a directory." + exit 1 + else + mkdir -p -m 700 $file || { echo "Can't create directory '$file'."; exit 1; } + chown $opt_runas $file + fi + done + # sender module initialization + if [ "$3" = "sender" ] ; then + valueof $path/$(eval echo $4) SpoolDir > /dev/null 2>&1 + if [ ! -e "$REPLY/spool.dat" ] ; then + touch $REPLY/.renumbered && chown $opt_runas $REPLY/.renumbered + fi + fi + fi + done < $opt_config + + # check others directories + for path in /var/lib/echelog/{socks,run} /var/{cache,log}/echelog ; do + if [ ! -e $path ] ; then + mkdir -p -m 700 $path # && chown $opt_runas $path + fi + done +} + +function kill_pid { + REPLY=$* + retry=0 + while [ "$REPLY" ]; do + retry=$[$retry+1] + if [ $retry == 1 ] ; then + $(dirname $bin)/echelogctl stop && sleep 5 || break + REPLY=`ps ho pid $REPLY` + continue + fi + if [ $retry -le 3 ]; then kill -CONT $REPLY && kill -$STOP_FIRST_WITH $REPLY || break; sleep $retry + elif [ $retry -gt 3 ]; then kill -9 $REPLY || break; sleep 1 + else break; fi + REPLY=`ps ho pid $REPLY` + done +} + +function do_stop { + local pname=$1 + local instname=$2 + local pid + local retry + shift + + pname=${procname:-$pname} + + # stop service from pidof data + svc_pidof -o $$ $pname > /dev/null + echo "# Stopping process $pname${instname:+[$instname]} (pids : $REPLY) ..." + retry=0 + + kill_pid $REPLY + + if [ "$REPLY" ]; then + echo " ==> stop $pname${instname:+[$instname]} Failed. (pids : $REPLY)" + return 1 + else + declare -F fct_post_stop >/dev/null && fct_post_stop $pname $instname + echo " ==> stop $pname${instname:+[$instname]} Done." + return 0 + fi +} + + +function fct_post_stop { + while read ; do + set -- $REPLY + if [ "$1" == Define ] ; then + kill_pid $( ps ho pid -C $( basename $( eval echo $3) ) ) + fi + done < $opt_config +} + + +function do_status { + local pname=$1 + local instname=$2 + local pids return=0 + shift + + pname=${procname:-$pname} + + # get info from pidof command + svc_pidof -o $$ $pname > /dev/null ; pids=$REPLY + if [ "$pids" ] ; then + echo "Process $pname${instname:+[$instname]} running without pidfile:$pids" + else + echo "Process $pname${instname:+[$instname]} stopped (no pidfile used)." + return=1 + fi + pids="" + while read ; do + set -- $REPLY + if [ "$1" == Define ] ; then + pids=${pids:+$pids }$( ps ho pid -C $( basename $( eval echo $3) ) ) + fi + done < $opt_config + if [ "$pids" ] ; then + echo "Children processes running pidfile:$( echo $pids )" + fi + return $return +} + +function do_install { + valueof /etc/echelog/modules/sender.conf PrivateKeyFile > /dev/null + keyfile=$REPLY + valueof /etc/echelog/modules/sender.conf CertificateFile > /dev/null + certfile=$REPLY + + if [ ! -e $keyfile ] ; then + # generate key + openssl genrsa -out $keyfile 1024 || exit 1 + fi + if [ ! -s $certfile ] ; then + echo -n "Country [FR]: " ; read COUNTRY ; COUNTRY=${COUNTRY:-FR} + echo -n "State []: "; read STATE + echo -n "Locality []: "; read LOCALITY + echo -n "Organisation Name []: " ; read ORGA_NAME + echo -n "Organisation Unit []: " ; read ORGA_UNIT + echo -n "Common Name [$HOSTNAME]: " ; + read COMMON_NAME ; COMMON_NAME=${COMMON_NAME:-$HOSTNAME} + echo -n "Email Address []: " ; read EMAIL + + ( echo "[ req ]" ; + echo "default_bits = 1024" + echo "default_keyfile = keyfile.pem" + echo "distinguished_name = req_distinguished_name" + echo "attributes = req_attributes" + echo "prompt = no" + echo "[ req_distinguished_name ]" + [ "$COUNTRY" ] && echo "C = $COUNTRY" + [ "$STATE" ] && echo "ST = $STATE" + [ "$LOCALITY" ] && echo "L = $LOCALITY" + [ "$ORGA_NAME" ] && echo "O = $ORGA_NAME" + [ "$ORGA_UNIT" ] && echo "OU = $ORGA_UNIT" + [ "$COMMON_NAME" ] && echo "CN = $COMMON_NAME" + [ "$EMAIL" ] && echo "emailAddress = $EMAIL" + echo "[ req_attributes ]" ) > /tmp/req.txt + + openssl req -new -days 1200 -nodes -key $keyfile \ + -out /tmp/req.pem -config /tmp/req.txt || exit 1 + echo "Merci de certifier la requête suivant:" + cat /tmp/req.pem + echo "Le certificat généré:" + cat > $certfile + fi +} + +function do_check { + echo "$HOSTNAME $1.$2 $(date +%s) RUNNING 0 OK" +} + +load_config + diff --git a/sbin/init.d/firewall b/sbin/init.d/firewall new file mode 100755 index 0000000..79793a0 --- /dev/null +++ b/sbin/init.d/firewall @@ -0,0 +1,212 @@ +#!/bin/bash + +. `dirname $0`/functions + +option confdir standard_option /etc/firewall +option current standard_option current +option backup standard_option backup +option hashsize standard_option 65535 +option forward boolean_option 1 +option filter boolean_option 1 +option stateful boolean_option 1 +option nat boolean_option + +IPTABLES=/sbin/iptables +IPRESTORE=/sbin/iptables-restore + +function do_help { + echo "Usage: ${0##*/} <status|start|revert|stop|route|block>" + echo "List of config.rc options (name, type, default value, current value) :" + echo + echo " - confdir : dir ; def='/etc/firewall' ; cur=$opt_confdir" + echo " - current : subdir ; def='current' ; cur=$opt_current" + echo " - backup : subdir ; def='backup' ; cur=$opt_backup" + echo " - hashsize : integer ; def=65535 ; cur=$opt_hashsize" + echo " - forward : boolean ; def=1 ; cur=$opt_forward" + echo " - filter : boolean ; def=1 ; cur=$opt_filter" + echo " - stateful : boolean ; def=1 ; cur=$opt_stateful" + echo " - nat : boolean ; def= ; cur=$opt_nat" + echo + echo "The configuration file is $opt_confdir/$opt_current/conf-$(uname -n).ipt" + echo + exit 1 +} + +# it will try to unload module $1 and all modules which depend on it +function recursive_rmmod { + local -a args + local mod + + while : ; do + args=( $(/sbin/lsmod|grep "^$1 "|tr -d '\[\]') ) + [ ${#args[@]} -gt 0 ] || return 0 + if [ "${args[2]}" = "0" ]; then + rmmod $1 + return $? + else + mod=3 + while [ $mod -lt ${#args[@]} ]; do + if ! recursive_rmmod ${args[$mod]}; then + echo "Error: could not unload module ${args[$mod]}." + return 1 + fi + (( mod++ )) + done + fi + done +} + +# starts the firewall with the specified config. +# if none is specified, no configuration is loaded. +# - disables ip_forwarding. It's up to the caller to +# enable it after initialization. +# - sets INPUT/OUTPUT/FORWARD policies to DROP +# returns 1 if the config could not be loaded. +function start_with_config { + local table chain chains + + echo 0 > /proc/sys/net/ipv4/ip_forward + + echo "Firewall: loading modules..." + /sbin/modprobe ip_tables + /sbin/modprobe iptable_filter + if [ -n "$opt_stateful" ]; then + /sbin/modprobe ip_conntrack hashsize=$opt_hashsize + [ -n "$opt_nat" ] && /sbin/modprobe iptable_nat + fi + + # filter chain has a default policy set to DROP + echo "Firewall: setting default policy to DROP..." + for chain in INPUT OUTPUT FORWARD; do + $IPTABLES -t filter -P $chain DROP + done + + # flush all rules in all tables + echo "Firewall: Flushing all rules..." + for table in mangle filter ${opt_stateful:+${opt_nat:+nat}}; do + $IPTABLES -t $table -F + $IPTABLES -t $table -X + done + + # other chains have a default policy set to ACCEPT + for table in mangle ${opt_stateful:+${opt_nat:+nat}}; do + chains=$($IPTABLES -t $table -L | grep "^Chain " | cut -f2 -d' ') + for chain in $chains; do + $IPTABLES -t $table -P $chain ACCEPT + done + done + + if [ -n "$1" ]; then + echo "Firewall: loading configuration file $opt_confdir/$1..." + if ! [ -r "$opt_confdir/$1" ] || ! $IPRESTORE < $opt_confdir/$1; then + echo "Firewall: Error! cannot load configuration file !" + return 1 + fi + fi + return 0 +} + +# checks wether the firewall modules are loaded +function do_status { + if [ -e /proc/net/ip_tables_names ]; then + if [ -n "$(cat /proc/net/ip_tables_names)" ]; then + echo "Firewall modules are loaded." + return 0 + fi + fi + echo "Firewall modules are not loaded." + return 1 +} + +# stops the firewall and unloads the modules +function do_stop { + # stop forwarding + echo "Firewall: disabling IP forwarding..." + echo 0 > /proc/sys/net/ipv4/ip_forward + + if [ -e /proc/net/ip_tables_names ] ; then + echo "Firewall: flushing all rules..." + # flush all rules in all tables + for table in $(cat /proc/net/ip_tables_names); do + $IPTABLES -t $table -F + $IPTABLES -t $table -X + # all chains have a default policy set to ACCEPT + chains=$($IPTABLES -t $table -L | grep "^Chain " | cut -f2 -d' ') + for chain in $chains; do + $IPTABLES -t $table -P $chain ACCEPT + done + done + fi + + # then unload the firewall modules + echo "Firewall: unloading modules..." + recursive_rmmod iptable_nat + recursive_rmmod ip_conntrack + recursive_rmmod iptable_filter + recursive_rmmod ip_tables + echo "Firewall: unloaded successfully." +} + +# block all incoming/outgoing traffic, but allows local +# communications +function do_block { + do_stop + + # we force some options to ensure proper blocking + unset opt_stateful + unset opt_forward + opt_filter=1 + + start_with_config + echo "Firewall: Changing policy to block external traffic..." + $IPTABLES -t filter -A INPUT -i lo -j ACCEPT + $IPTABLES -t filter -A OUTPUT -o lo -j ACCEPT + $IPTABLES -t mangle -P PREROUTING DROP + $IPTABLES -t mangle -P INPUT DROP + $IPTABLES -t mangle -P FORWARD DROP + $IPTABLES -t mangle -P POSTROUTING DROP + $IPTABLES -t mangle -P OUTPUT DROP + $IPTABLES -t mangle -A PREROUTING -i lo -j ACCEPT + $IPTABLES -t mangle -A INPUT -i lo -j ACCEPT + $IPTABLES -t mangle -A POSTROUTING -o lo -j ACCEPT + $IPTABLES -t mangle -A OUTPUT -o lo -j ACCEPT + echo "Firewall: done." +} + +# load current configuration +function do_start { + do_stop + if start_with_config ${opt_filter:+$opt_current/conf-$(uname -n).ipt}; then + if [ -n "$opt_forward" ]; then + echo "Firewall: enabling IP forwarding..." + echo 1 > /proc/sys/net/ipv4/ip_forward + fi + fi + echo "Firewall: done." +} + +# load backup configuration +function do_revert { + do_stop + if start_with_config ${opt_filter:+$opt_backup/conf-$(uname -n).ipt}; then + if [ -n "$opt_forward" ]; then + echo "Firewall: enabling IP forwarding..." + echo 1 > /proc/sys/net/ipv4/ip_forward + fi + fi + echo "Firewall: done." +} + +# unload the firewall and enable ip forwarding +function do_route { + do_stop + # enable ip forwarding + if [ -n "$opt_forward" ]; then + echo "Firewall: enabling IP forwarding..." + echo 1 > /proc/sys/net/ipv4/ip_forward + fi + echo "Firewall: done." +} + +load_config + diff --git a/sbin/init.d/functions b/sbin/init.d/functions new file mode 100755 index 0000000..b041321 --- /dev/null +++ b/sbin/init.d/functions @@ -0,0 +1,906 @@ +#!/bin/bash + +# +# sbin/init.d/functions - Formilux init script - version 0.3.14 - 2003-06-19 +# +# Copyright (C) 2001-2003 Benoit Dolez & Willy Tarreau +# mailto: benoit@ant-computing.com,willy@ant-computing.com +# +# This program is licenced under GPLv2 ( http://www.gnu.org/licenses/gpl.txt ) + +# not used ? ## DEBUG FILE +# not used ? #DEBUG=/tmp/.flx.$PID.$RANDOM +# not used ? #[ -e "$DEBUG" ] && rm -f $DEBUG && touch $DEBUG +# not used ? #if [ $? != 0 ] ; then DEBUG="" ; fi + +# Test for previous sourcing already in progress +declare -F build_default_func > /dev/null && return + +# SSHD starts this script with "-c" followed by all the parameters grouped into +# one single string. So we expand it to allow remote commands. +if [ "$1" = "-c" ]; then shift; set -- $*; fi + +# Configuration file to use. Default : /etc/config.rc +export CONFIG=${CONFIG:-/etc/config.rc} + +# Path to startup scripts. Default : /sbin/init.d +# INIT_PATH=${INIT_PATH:-/sbin/init.d} +INIT_PATH=${INIT_PATH:-`dirname $0`} + +# Process name +PNAME=`basename $0` +PPATH=`dirname $0` +PFULLNAME=$0 + +# Global variable for status information. Set to "1" while processing the right +# section. +RUNNING_SECTION= + +# goes "1" if at least one instance of the required service has been found +SVC_FOUND= + +# no particular function defined yet +DEFINED_FUNCTIONS= + +# not in list mode +MUST_LIST_SECTIONS= + +# no option filter +OPTION_FILTER= + +# signal to use at first when stopping a service. Default: TERM +# May be changed by any init script (eg: sshd) +STOP_FIRST_WITH=TERM + +# set with --force to ignore current status +FORCE_START_STOP=0 + +# controls wether the service is being started with --auto +SVC_AUTO_START=0 + +# facility for syslog message +G_FACILITY=local3 + +# LOG FILE +LOGFILE=/var/log/startup.log +[ -L "$LOGFILE" ] && rm -f $LOGFILE + +# the scripts can list some global variables which they use and that should be +# unset after processing the service. This is to be set globally. +SVC_VARS= + +# this is set to $? for the first do_xxx which doesn't return 0 +STATUS_RET=0 + +######################################## +# BASIC FUNCTIONS # +######################################## +function logit { + # echo -n "'" + # echo -n "$*" | sed -e "s/'/\\\\'/" -e "s/§/' '/g" + # echo "'" + echo " $*" + [ "${1##\#*}" -a "xG_FACILITY" != x ] && \ + logger -p $G_FACILITY.info -t "flxi[$$].$PNAME" -- \ + "exec[$USER]: $*" + $* + local return=$? + [ $return != 0 -a "xG_FACILITY" != x ] && \ + logger -p $G_FACILITY.info -t "flxi[$$].$PNAME" -- \ + "exec.error[$USER]: $return" + return $return +} + +# returns the value for a given parameter in a config file. The value is both +# echoed and set to the REPLY variable. +# The value is found this way : +# [ \t]*<parameter>[:= \t]*<value>[#]*<comment>$ + +# usage: valueof CONFIGFILE PARAMETER +function valueof { + if [ -e "$1" ]; then + REPLY=$(grep $'^[ \t]*'"$2"'[:= \t]*' $1|sed s,'^\('$'[ \t]*'"$2"$'[ \t:=]*''\)\([^#]*\).*$,\2,') + else + REPLY= + fi + echo $REPLY +} + +# returns children processes ids. +# usage: getchild PID ... +function childrenpid { + local found + local pid=" $* " + + set -- $( exec ps ahxo ppid,pid ) ; while [ $# -gt 0 ] ; do + [ -z "${pid/* $1 */}" ] && found="$found $2" ; shift ; shift ; done + + REPLY="" && [ "$found" ] && REPLY=$found && echo $REPLY +} + + +# Returns process id from process name only by looking at the process table. +# (ie: no pidfile used). Only processes which have ppid of 1 (or parent_pid) +# are returned. A list of pids to omit can be specified with "-o". +# If no process name is specified, all the parent's children are returned. +# svc_pidof [ -o "omit_pids*" ]* [ -p parent_pid ] [ PNAME ... ] +function svc_pidof { + local omit=x + local ppid=1 + local comm + local found + + while [ $# -gt 0 ] ; do + if [ "x$1" = "x-o" ] ; then omit="$omit ${2/%PPID/$$} " ; shift 2 + elif [ "x$1" = "x-p" ] ; then ppid="$2" ; shift 2 + else comm="$comm $1 " ; shift 1 + fi + done + + #set -- "$( exec ps ahxo pid,ppid,comm )" ; set -- $( echo "$1" | awk '{ print $1,$2,$3}' ) + set -- $( ps ahxo pid,ppid,comm | awk '{ print $1,$2,$3}' ) + while [ $# -gt 0 ] ; do + [ -z "${comm/* $3 */}" -a -n "${omit/* $1 */}" -a "$2" = "$ppid" ] && found="$found $1" + shift ; shift ; shift + done + REPLY="" && [ "$found" ] && REPLY=$found && echo $REPLY +} + +# This function starts the given process in background, in a new session, +# and with all its I/O closed, to ensure that it will not block a TTY if +# a lazy coder didn't think appropriate to close the file descriptors +# before forking. +function daemon { + setsid "$@" <&- 1<&- 2<&- & +} + +###################### +# EXPORTED FUNCTIONS # +###################### + +# this eventually remounts the filesystem hosting the directory given in the +# argument read-write. +# It returns : +# - 0 if it was RO and has successfully been remounted RW +# - 1 if it was already RW +# - 2 if it could not be remounted RW + +function remount_rw { + local root + set -- $(df $1|tail +2) + root=$6 + set -- $(grep -v '^rootfs' /proc/mounts |cut -f2- -d' '|grep "^$root ") + if [ "${3/rw//}" != "$3" ]; then + return 1 + fi + echo -n " - remounting $root read-write ..." + if remountw $root >/dev/null 2>&1; then + echo " => done." + return 0 + else + echo " => failed." + return 2 + fi +} + +# this eventually remounts the filesystem hosting the directory given in the +# argument read-only. +# It returns : +# - 0 if it was RW and has successfully been remounted RO +# - 1 if it was already RO +# - 2 if it could not be remounted RO + +function remount_ro { + local root + set -- $(df $1|tail +2) + root=$6 + set -- $(grep -v '^rootfs' /proc/mounts |cut -f2- -d' '|grep "^$root ") + if [ "${3/ro//}" != "$3" ]; then + return 1 + fi + echo -n " - remounting $root read-only ..." + if remountr $root >/dev/null 2>&1; then + echo " => done." + return 0 + else + echo " => failed." + return 2 + fi +} + +######################################## +# CONFIGURATION FILE LOADING FUNCTIONS # +######################################## + +# All functions handling options get the option name as a first argument, +# then the rest of the line follows. + +# default function for config directive. This one is called only for unmapped +# options, so either bad ones or unused services. +function default_config_option { + [ "$RUNNING_SECTION" ] && echo "Bad option '$1' in '$*'" +} + +# builtin function to create a variable from an option. +# The variable name is "opt_$option" where option is the option name. +function standard_option { + if [ "x$2" = "x--disable" ]; then + eval "opt_$1=" + else + eval "opt_$1='$2'" + fi +} + +# builtin function to create a variable from an option. +# The variable name is "opt_$option" where option is the option name. +function boolean_option { + if [ "x$2" = "x--disable" ]; then + eval "opt_$1=0" + else + eval "opt_$1=1" + fi +} + +# builtin function to create a variable from an option. +# The variable name is the same as the option name. +# This is mainly used for reserved options such as "bin" and "cmdline", +# or to port older startup scripts. +# The option value is NOT evaluated now, which means that cmdline can refer to +# $bin if properly quoted. Eg: cmdline '$bin -f $config' +function reserved_option { + if [ "x$2" = "x--disable" ]; then + eval "$1=" + else + eval "$1='$2'" + fi +} + +# builtin function to create a variable from an option. +# The variable name is "opt_$option" where option is the option name. +function long_option { + if [ "x$2" = "x--disable" ]; then + eval "opt_$1=" + else + local optname=$1 + shift + eval "opt_$optname='$*'" + fi +} + +# builtin function to create an array from an option. +# The variable name is "opt_$option" where option is the option name. +# The array is extended with all the args for each occurence of the option. +# If no arg is given, the option is extended with a single dash '#' so that +# we further know that it has been called. +function multiple_option { + if [ "x$2" = "x--disable" ]; then + # in case of multiple_option, "no <option> <args>" only + # means that we don't want to add <args> to <option>, + # but not that we want to clear <option> + # eval "opt_$1=( )" + : + else + local optname=$1 + shift + if [ $# -gt 0 ]; then + #eval "opt_$optname=( \$opt_$optname \"$*\" )" + eval "opt_$optname[\${#opt_$optname[*]}]='$*'" + else + # if no option is set, this reference will be lost because in fact + # it will be added as an empty entry in the list. So we replace it + # with a dash '#' to mark it as referenced. + eval "opt_$optname[\${#opt_$optname[*]}]='#'" + fi + fi +} + +# default start function +# usage : do_start process_name [instance_name] +# if functions fct_pre_start() and fct_post_start() are defined, they will be +# called just before and just after the cmdline. +function do_start { + local p=$1 + local instname=$2 + local ret + do_status $p $instname > /dev/null 2>&1 + if [ $? = 0 -a $FORCE_START_STOP -eq 0 ] ; then + echo "Process $p${instname:+[$instname]} already running." + [ $SVC_AUTO_START -eq 0 ] && echo " ==> please use '--force' or 'restart' instead or check with 'status'." + return 0 + fi + + echo "# Starting $p${instname:+[$instname]} ..." + declare -F fct_pre_start >/dev/null && fct_pre_start $p $instname + logit $cmdline + ret=$? + declare -F fct_post_start >/dev/null && fct_post_start $p $instname + [ $ret -eq 0 ] && echo " ==> start $p${instname:+[$instname]} Done." || \ + { echo " ==> start $p${instname:+[$instname]} Failed." ; return 1 ; } + return 0 +} + +# +# This function tries to stop the process whose pid is specified in the file +# in $1. It returns 0 if the process is stopped, or 1 if it is still running. +# There can be only one pid per pidfile. +# +# usage : do_stop_with_pidfile pidfile [process_name [instance_name]] +# if functions fct_pre_stop() and fct_post_stop() are defined, they will be +# called just before and just after a successful kill sequence. +function do_stop_with_pidfile { + local pid + local pids + local pidfile=$1 + local pname=$2 + local instname=$3 + + svc_pidof -o $$ $pname > /dev/null ; pids=$REPLY + + if [ $FORCE_START_STOP -eq 0 ]; then + if ! [ -r "$pidfile" ] || { read pid REPLY <"$pidfile"; [ -z "$pid" ]; } || ! [ -L /proc/$pid/cwd ]; then + echo "# Process $pname${instname:+[$instname]} already stopped (according to $pidfile)${pids:+, but check pids : $pids}" + # ensure that we remove stale files + [ -e "$pidfile" ] && echo "Removing stale pid file" && rm -f "$pidfile" + return 0 + fi + fi + + valueof /proc/$pid/status Name >/dev/null ; set -- $REPLY + if [ "$pname" -a "x$pname" != "x$1" -a $FORCE_START_STOP -eq 0 ]; then + echo "# The pid in $pidfile points to a wrong process name ($pid:$1)${pids:+. Check $pids for $pname${instname:+[$instname]}}." + return 1; + fi + + echo "# Stopping $pname${instname:+[$instname]} (pid $pid according to $pidfile) ..." + declare -F fct_pre_stop >/dev/null && fct_pre_stop $pname $instname + kill -CONT $pid >/dev/null 2>&1 ; kill -$STOP_FIRST_WITH $pid >/dev/null 2>&1 + set -- 0 1 2 3 + while [ -L /proc/$pid/cwd -a $# -gt 0 ] ; do sleep $1 ; shift ; done + [ -L /proc/$pid/cwd ] && { kill -9 $pid >/dev/null 2>&1; sleep 1 ; } + [ -L /proc/$pid/cwd ] && { echo " ==> stop $pname${instname:+[$instname]} Failed." ; return 1; } + if [ -e "$pidfile" ]; then rm -f "$pidfile"; fi + declare -F fct_post_stop >/dev/null && fct_post_stop $pname $instname + echo " ==> stop $pname${instname:+[$instname]} Done." + return 0 +} + +# +# default stop function +# If a pidfile exists, it is used. Otherwise, all pids with same name which have +# init for parent will be killed. +# The function returns 0 if the process is(are) stopped, and 1 if not all could +# be stopped. +# +# usage : do_stop process_name [instance_name] +# if functions fct_pre_stop() and fct_post_stop() are defined, they will be +# called just before and just after a successful kill sequence. +function do_stop { + local pname=$1 + local instname=$2 + local pid + local retry + shift + + pname=${procname:-$pname} + # stop service from pidfile + [ "x$pidfile" != x ] && { do_stop_with_pidfile $pidfile $pname $instname; return $? ; } + + # stop service from pidof data + svc_pidof -o $$ $pname > /dev/null + if [ -z "$REPLY" ]; then + echo "# Process $pname${instname:+[$instname]} already stopped, cleaning up..." + declare -F fct_post_stop >/dev/null && fct_post_stop $pname $instname + echo " ==> stop $pname${instname:+[$instname]} Done." + return 0 + fi + echo "# Stopping process $pname${instname:+[$instname]} (pids : $REPLY) ..." + retry=$REPLY; # save it temporarily + declare -F fct_pre_stop >/dev/null && fct_pre_stop $pname $instname + REPLY=$retry; retry=0 + while [ "$REPLY" ]; do + retry=$[$retry+1] + if [ $retry -le 3 ]; then kill -CONT $REPLY >/dev/null 2>&1 && kill -$STOP_FIRST_WITH $REPLY >/dev/null 2>&1 || break; sleep $retry + elif [ $retry -gt 3 ]; then kill -9 $REPLY >/dev/null 2>&1 || break; sleep 1 + else break; fi + REPLY=`ps ho pid $REPLY` + done + if [ "$REPLY" ]; then + echo " ==> stop $pname${instname:+[$instname]} Failed. (pids : $REPLY)" + return 1 + else + declare -F fct_post_stop >/dev/null && fct_post_stop $pname $instname + echo " ==> stop $pname${instname:+[$instname]} Done." + return 0 + fi +} + +function do_restart { + do_stop $* + do_start $* +} + +# returns a basic check of the service, an returns one line of info of the form: +# <hostname> <service_name>.[instance_name] <date_in_secs> {RUNNING|STOPPED}[,more_info] [{OK|CONFIG_CHANGED}] +# returns 0 if running. +function do_check { + local run_stat + local status=OK + local ret uptime=0 + local pid + + do_status $1 $2 > /dev/null + ret=$? + if [ $ret -eq 0 ]; then + if [ "$REPLY" ]; then + for pid in $REPLY; do + uptime=$[$(date +%s)-$(date -d "`ps ho lstart $pid`" +%s)] + echo "`uname -n` $1.$2 `date +%s` RUNNING $uptime $status" + done + else + echo "`uname -n` $1.$2 `date +%s` RUNNING 0 $status" + fi + else + run_stat=STOPPED + case $ret in + 1) status=ALERT,nofile ;; + 2) status=ALERT,nopid ;; + 3) status=ALERT,other ;; + *) status=ALERT ;; + esac + echo "`uname -n` $1.$2 `date +%s` $run_stat $uptime $status" + fi + return $ret +} + +# returns 0 if the process is running, 1 if the pid file does not exist, +# 2 if the pid doesn't exist anymore, 3 if it has been affected to another +# process name. If the process is running, REPLY is set to its pid. +# usage : do_status_with_pidfile pidfile [process_name [instance_name]] +function do_status_with_pidfile { + local pidfile=$1 + local pname=$2 + local instname=$3 + local pid + + [ -r "$pidfile" ] || { echo "Process $pname${instname:+[$instname]} stopped (no pidfile present)" ; return 1 ; } + read pid < $pidfile + [ -L /proc/$pid/cwd ] || { echo "Process $pname${instname:+[$instname]} stopped (from pidfile)" ; return 2 ; } + valueof /proc/$pid/status Name >/dev/null ; set -- $REPLY + [ "$pname" -a "x$pname" = "x$1" ] || { + echo "Process with an other name ($1,$pid) already running." + echo " ==> you should remove invalid pidfile $pidfile" + return 3 + } + childrenpid $pid > /dev/null + local cpid=$* + echo "Process $pname${instname:+[$instname]} running : $pid ${cpid:+($cpid)}" + REPLY=$pid + return 0 +} + +# returns 0 if the process is running; 1 if it's stopped and there's no pid file, +# otherwise same as do_status_with_pidfile(). If the process is running, REPLY is +# set to its pid. +# usage : do_status process_name [instance_name] +function do_status { + local pname=$1 + local instname=$2 + shift + + pname=${procname:-$pname} + # get info from pidfile if it exist + [ "x$pidfile" != x ] && { do_status_with_pidfile $pidfile $pname $instname; return $? ; } + + # get info from pidof command + svc_pidof -o $$ $pname > /dev/null ; pids=$REPLY + [ "$pids" ] && { echo "Process $pname${instname:+[$instname]} running without pidfile : $pids" ; return 0 ; } + echo "Process $pname${instname:+[$instname]} stopped (no pidfile used)." + return 1 +} + +# lists all the known options for the current service, with their default or +# assigned values. There is a double eval so that options depending on others +# are correctly resolved. +# The output format is "process_name.[instance_name] option value" +# usage : list_options process_name [instance_name] +function do_list_options { + local i=0 + local occur=0 + local nbocc=0 + local inst="$1.$2" + + while [ $i -lt $svc_nbopts ]; do + if [ -z "$OPTION_FILTER" -o "$OPTION_FILTER" = "${svc_opts[$i]}" ]; then + + + if [ "${svc_fcts[$i]}" = "boolean_option" -o \ + "${svc_fcts[$i]}" = "standard_option" -o \ + "${svc_fcts[$i]}" = "long_option" -o \ + "${svc_fcts[$i]}" = "reserved_option" ]; then + eval eval echo $inst ${svc_opts[$i]} \$"${svc_vars[$i]}" + elif [ "${svc_fcts[$i]}" = "multiple_option" ]; then + eval nbocc='${#'"${svc_vars[$i]}"'[*]}' + if [ $nbocc -eq 0 ]; then # no value, let's at least show the option name + eval echo $inst ${svc_opts[$i]} + else + while [ $occur -lt $nbocc ]; do + eval eval echo $inst ${svc_opts[$i]} '${'"${svc_vars[$i]}"'[$occur]}' + occur=$[$occur+1] + done + fi + else + echo $inst ${svc_opts[$i]} "[defined by script]" + fi + fi + i=$[$i+1] + done +} + +# maps an option to a function. Existing options are simply overridden. +# usage: option option_name function_name [ defaults ] +function option { + local name=$1 + local fct=$2 + local def=$3 + local opt=0 + + # first, check if this option has already been defined, and return its + # index, or a new one if it's new. + while : ; do + if [ $opt -ge $svc_nbopts ]; then svc_nbopts=$[$opt+1]; break; fi + if [ "x$name" = "x${svc_opts[$opt]}" ]; then break; fi + opt=$[$opt+1] + done + + svc_opts[$opt]=$name + svc_fcts[$opt]=$fct + svc_defs[$opt]=$def + if [ "x$fct" = "xboolean_option" -o "x$fct" = "xstandard_option" -o \ + "x$fct" = "xlong_option" -o "x$fct" = "xmultiple_option" ]; then + svc_vars[$opt]=opt_$name + elif [ "x$fct" = "xreserved_option" ]; then + svc_vars[$opt]=$name + else + svc_vars[$opt]="" + fi + + #eval "function $1 { $2 $1 \$* ; }" +} + +# This function is called once at load time. It scans the config file for all +# referenced options, and assigns them to a quiet function which yells only +# an unknown option has been referenced in a requested section. The options are +# discovered by reading all the first words. +# +# usage: build_default_func config_file +function build_default_func { + local file=$1 + [ -f $file ] || return 1 + # undefine all previously defined functions + for func in $DEFINED_FUNCTIONS ; do unset -f $func ; done + DEFINED_FUNCTIONS=`awk '{gsub("#.*", "", $1); \ + if (match($1, "^[a-zA-Z0-9][a-zA-Z0-9_]*$")) \ + print $1 | "sort -u" }' $file ` + # get all first words and build a default function + for i in $DEFINED_FUNCTIONS ; do + if ! eval "declare -F $i > /dev/null" ; then + eval "function $i { default_config_option $i \$* ; } " + fi + done +} + +# default 'service' function. +# Called as default_service svc_name [svc_instance] from load_config. +# SVC_ARGS is set from the service command line, and is used at next one. +function default_service { + local ret + local opt + local val + # skip first parameter (probably 'service') + #shift + + # we're in listing mode, we do nothing except listing the services + if [ "$MUST_LIST_SECTIONS" = 1 -a $# -ge 1 ]; then + [ "$1" != "${SVC_ARGS[0]}" -o "$2" != "${SVC_ARGS[1]}" ] && echo $* + SVC_ARGS=( $* ) + return + fi + + # check for running selected service + if [ "$RUNNING_SECTION" = 1 ]; then + # first, we'll check wether the next service is *exactly* the same as + # the current one, in which case they are merged, in order to avoid + # duplicate starts (system for example) + if [ "$PNAME" = "$1" -a "${SVC_ARGS[0]}" = "$2" ]; then + return + fi + + # try to insert command-line options + while [ "$FORCE_OPTIONS" ]; do # "opt=val,opt=val..." + opt=${FORCE_OPTIONS%%,*} + val=${opt#*=} + opt=${opt%%=*} + eval $opt $val + if [ "${FORCE_OPTIONS%%*,*}" ]; then # no more ',' + break; + else + FORCE_OPTIONS=${FORCE_OPTIONS#*,} + fi + done + + # unset all options to avoid conflicts with commands (eg: modprobe, ip ...) + for i in $DEFINED_FUNCTIONS; do + case "$i" in + service|section|interface) ;; + *) unset -f $i ;; + esac + done + + # force a last eval on each reserved option so that they can refer to + # each other. + for i in bin pidfile procname cmdline; do eval eval "$i=\\\"\$$i\\\""; done + + # now if the script defines a fct_end_section() function, let's call + # it to fix some values, or extract som from external config files. + declare -F fct_end_section > /dev/null && fct_end_section $PNAME ${SVC_ARGS[*]} + + + if [ "$SVC_AUTO_START" = 0 -o "$autostart" = 1 ]; then + if declare -f do_$ACTION >/dev/null; then + do_$ACTION $PNAME ${SVC_ARGS[*]} + else + if declare -f do_help >/dev/null; then + do_help + else + echo "Error: Unknown action : $ACTION" + fi + fi + fi + ret=$? + if [ $ret -gt 0 ]; then + STATUS_RET=$ret + fi + + if [ "x$G_FACILITY" != x ] ; then + if [ "x$ACTION" = xstart -o "x$ACTION" = xstop \ + -o "x$ACTION" = xrestart ] ; then + if [ $ret -gt 0 ] ; then + logger -p $G_FACILITY.err -t flxi[$$].$PNAME -- \ + "error[$USER]: $PNAME $ACTION ${SVC_INSTANCE[*]} = $ret" + else + logger -p $G_FACILITY.info -t flxi[$$].$PNAME -- \ + "done[$USER]: $PNAME $ACTION ${SVC_INSTANCE[*]}" + fi + fi + fi + unset -v RUNNING_SECTION SVC_ARGS bin cmdline pidfile procname $SVC_VARS + + # reset all options to the default option + for i in $DEFINED_FUNCTIONS; do + case "$i" in + service|section|interface) ;; + *) unset -f $i + eval "function $i { default_config_option $i \$* ; } " + ;; + esac + done + fi + + # if service is the one wished, start it at the end + if test "x$1" = "x$PNAME" -a \ + \( "x$2" = "x${SVC_INSTANCE[0]}" -o "x${SVC_INSTANCE[0]}" = "x" \) ; then + # we can test difference between SVC_ARGS and SVC_INSTANCE + SVC_FOUND=1 + RUNNING_SECTION=1 + shift + SVC_ARGS=( $* ) + + # reset every variable + unset -v ${svc_vars[*]} + + # map all options to their functions, and set default vars. + i=0 + while [ $i -lt $svc_nbopts ]; do + eval "function ${svc_opts[$i]} { ${svc_fcts[$i]} ${svc_opts[$i]} \$* ; } " + if [ "${svc_vars[$i]}" ]; then + if [ "x${svc_fcts[$i]}" != "xmultiple_option" ]; then + eval "${svc_vars[$i]}='${svc_defs[$i]}'" + else + eval "${svc_vars[$i]}=( )" + fi + fi + i=$[$i+1] + done + + # now if the script defines a fct_begin_section() function, let's call + # it to preset some default values from external config files. + unset -v $SVC_VARS + declare -F fct_begin_section > /dev/null && fct_begin_section $PNAME ${SVC_ARGS[*]} + fi +} + +# 'no' for 'no ... ', disable a service or an option +function default_no { + local req=$1 + shift + case "$req" in + "service") + default_service + ;; + "section") + default_service + ;; + "interface") + default_service + ;; + *) + if [ "$MUST_LIST_SECTIONS" = 1 ]; then + return + fi + local opt=0 + while : ; do + if [ $opt -ge $svc_nbopts ]; then + # non error since we don't know if this is a valid word. + return + fi + if [ "x$req" = "x${svc_opts[$opt]}" ]; then + if [ "x${svc_fcts[$opt]}" != "xmultiple_option" ]; then + eval "${svc_vars[$opt]}=''" + else + # in case of multiple_option, "no <option> <args>" only + # means that we don't want to add <args> to <option>, + # but not that we want to clear <option> + # eval "${svc_vars[$opt]}=( )" + : + fi + break + fi + opt=$[$opt+1] + done + + # this doesn't work because $req is launched under a subshell ! + #if declare -F $req >/dev/null; then + # eval "$req --disable $*" + #fi + esac +} + +# source configuration file, called last. +function load_config { + # defines functions for all first words in the config file + build_default_func $CONFIG + + # defines functions for reserved keywords: no, service, section, interface. + function no { default_no $*; } + function service { default_service $*; } + function section { default_service $*; } + function interface { + if [ "$PNAME" = "network" ]; then + echo "Warning: use of 'interface $1' keyword is deprecated. Use 'section network $1' instead."; + fi + default_service network $*; + } + + if test ! -d "$CONFIG" -a -e "$CONFIG" ; then + # first keywords out of a section space are for the system, so let's enter + # automatically in system section. + service system + . $CONFIG + service "" + fi + + if [ "$SVC_FOUND" != 1 -a "$MUST_LIST_SECTIONS" != 1 ]; then + echo "Service/instance not found in $CONFIG, using default values." + service $PNAME ; service "" + + #[ "x$G_FACILITY" != x ] && \ + # logger -p $G_FACILITY.warn -t "flxi[$$].$PNAME" -- \ + # "unknown[$USER]: $PNAME $ACTION ${SVC_INSTANCE[*]}" + exit 1 + fi + return $STATUS_RET +} + +# abort the process after displaying an error message. +die() { + echo $* >&2 + exit 1 +} + +################################## +# ALWAYS LOADED WHEN SOURCED # +################################## +# build default undefined functions + +svc_opts=( ) +svc_vars=( ) +svc_defs=( ) +svc_fcts=( ) +svc_nbopts=0 + +while [ $# -gt 0 ] ; do + case "$1" in + -f|--file) # use this configuration file + export CONFIG=$2 + shift 2 || die "Error: missing arg for --file, try --help." + ;; + --auto) # only start services which don't have a "no autostart" statement + SVC_AUTO_START=1 + shift + ;; + --force) # force start or stop disregarding current status + FORCE_START_STOP=1 + shift + ;; + --list_sections) # list all known sections + MUST_LIST_SECTIONS=1 + load_config + exit 0 + ;; + --filter_option) # display only this option in list_options + OPTION_FILTER=$2 + shift 2 || die "Error: missing arg for --filter_option, try --help." + ;; + -o|--option) # force options : -o "opt=val,opt=val..." + FORCE_OPTIONS=$2 + shift 2 || die "Error: missing arg for --option, try --help." + ;; + -*) + echo "Common commands : start, stop, restart, status, check, list_options." + echo "Global options :" + grep $'^[ \t]*-[-a-z0-9_|]*)[ \t]*# ' $PPATH/functions | \ + sed -e $'s/^\\([ \t]*\\)\\([^)]*\\)\\([ \t#)]*\\)\\(.*\\)/ \\2\t\t\\4/' + echo "Other options :" + declare -F usage > /dev/null && usage $* || \ + echo " -h|--help display this help" && \ + [ "x$USAGE" != x ] && echo "$USAGE" + exit 1 + ;; + *) + break + ;; + esac +done + +# Assign the requested action to ACTION (first arg). Default : start +ACTION=${1:-start}; shift + +# Assign the requested instances to SVC_INSTANCE. Default : "" +SVC_INSTANCE=( $* ) + +# most services don't need to redefine the keywords "bin", "cmdline", +# "pidfile", "procname" and "check_interval", so let's initialize them now. +# This also means that any service can use these options without declaring them. +option bin reserved_option +option cmdline reserved_option '$bin' +option pidfile reserved_option +option procname reserved_option +option check_interval reserved_option 0 +option autostart reserved_option 1 + +return 0 + +######### end of script, here comes some documentation ######### + +When a service is started, these operations are performed for each section +containing the same name, and the same instance name if any, or any instance if +no name is set : + + - options variables are initialized to their default values + - if fct_begin_section() exists, it is called with service name and instance name + - options are interpreted + - bin,pidfile,cmdline,procname are converted through an eval so that they can + reference variables options with '$name' or '$opt_name'. + - if fct_end_section() exists, it is called with service name and instance name + - if do_start() exists, it is called with service name and instance name. + Otherwise, the default do_start() function is called with same args. This + function calls fct_pre_start() with same args if it exists, just before + starting $cmdline, and then fct_post_start() just after. + +In case of a stop, everything is the same except do_start() which is replaced +with do_stop(). This last one also calls fct_pre_stop() and fct_post_stop(), +but this last one only if the stop is successful. + +If the service is started as "service --auto start", the option "autostart" is +checked, and if set to 0, the service will not start. This is useful to +differentiate between configured services and enabled services. diff --git a/sbin/init.d/keyboard b/sbin/init.d/keyboard new file mode 100755 index 0000000..a3367b7 --- /dev/null +++ b/sbin/init.d/keyboard @@ -0,0 +1,18 @@ +#!/bin/bash + +. `dirname $0`/functions + +option keymap standard_option us +option keyrate standard_option 30 + +function do_start { + loadkeys $opt_keymap + kbdrate -r $opt_keyrate +} + +function do_stop { + loadkeys us +} + +load_config + diff --git a/sbin/init.d/klogd b/sbin/init.d/klogd new file mode 100755 index 0000000..5f4107b --- /dev/null +++ b/sbin/init.d/klogd @@ -0,0 +1,11 @@ +#!/bin/bash + +. `dirname $0`/functions + +option pidfile reserved_option /var/run/klogd.pid +option bin reserved_option /sbin/klogd +option console_level standard_option 4 +option kernel_symbols standard_option /boot/`uname -r`/System.map +option cmdline reserved_option '$bin ${opt_console_level:+-c $opt_console_level} ${opt_kernel_symbols:+-k $opt_kernel_symbols}' + +load_config diff --git a/sbin/init.d/logrotate b/sbin/init.d/logrotate new file mode 100755 index 0000000..d9a9e3a --- /dev/null +++ b/sbin/init.d/logrotate @@ -0,0 +1,16 @@ +#!/bin/bash + +. `dirname $0`/functions + +option bin reserved_option /usr/sbin/logrotate +option cmdline reserved_option '$bin -s $opt_status' +option statusfile standard_option /var/lib/logrotate.status + +function fct_pre_start { + local t=$( dirname $opt_statusfile ) + if [ ! -d $t ] ; then + mkdir -p -m 755 $t || return 1 + fi +} + +load_config diff --git a/sbin/init.d/monitor b/sbin/init.d/monitor new file mode 100755 index 0000000..59cbb16 --- /dev/null +++ b/sbin/init.d/monitor @@ -0,0 +1,46 @@ +#!/bin/bash + +. `dirname $0`/functions + +option default_check_interval standard_option 300 +option check_interval standard_option 60 +option facility standard_option +option try_restart boolean_option +option html standard_option +option bin reserved_option /opt/exosec/bin/monitor +option cmdline reserved_option \ + '$bin -p $pidfile ${opt_html:+--html $opt_html} ${opt_facility:+--syslog $opt_facility} ${opt_try_restart:+--restart}' +option pidfile reserved_option /var/run/monitor.pid + +function do_check { + local run_stat pid next_stat uptime + + if [ $CONFIG -nt $pidfile ] ; then + status=CONFIG_CHANGED + else + status=OK + fi + + if do_status $1 $2 > /dev/null ; then + run_stat=RUNNING + uptime=$[ $( date +%s ) - $( date -d "$( ps ho lstart $REPLY)" +%s ) ] + + read pid < $pidfile + set -- $( ps ahxo ppid,pid,comm,lstart | \ + awk '{if ($1 == '$pid' && $3 == "sleep") print $0 } ') + if [ $# == 0 ] ; then + status=$status,$opt_check_interval + else + pid=$2 ; shift 3 ; start=$( date -d "$*" +%s) + next_stat=$[ $opt_check_interval - $(date +%s) + $start ] + status=$status,$next_stat + fi + else + uptime=0 + run_stat=STOPPED + fi + + echo "$HOSTNAME $PNAME. $(date +%s) $run_stat $uptime $status" +} + +load_config diff --git a/sbin/init.d/mouse b/sbin/init.d/mouse new file mode 100755 index 0000000..c45aae7 --- /dev/null +++ b/sbin/init.d/mouse @@ -0,0 +1,23 @@ +#!/bin/bash + +. `dirname $0`/functions + +option type standard_option ps2 +option device standard_option /dev/mouse +option bin reserved_option /usr/sbin/gpm +option procname reserved_option gpm +option cmdline reserved_option '$bin -t $opt_type -m $opt_device' +option pidfile reserved_option /var/run/gpm.pid + +# gpm is buggy, it doesn't close its std* before forking, so the startup +# script hang at boot time because it hogs the terminal. +function fct_pre_start { + #exec 10>&0 11>&1 12>&2 + exec </dev/null >&0 2>&0 +} + +function fct_pre_stop { + $cmdline -k >/dev/null 2>&1 +} + +load_config diff --git a/sbin/init.d/network b/sbin/init.d/network new file mode 100755 index 0000000..061778c --- /dev/null +++ b/sbin/init.d/network @@ -0,0 +1,457 @@ +#!/bin/bash + +# service network [<ifname>] # interface name -> int_<ifname>=enable +# ip address <ip/mask> [secondary] # address for this interface +# media {auto|full|fdx|100full|100fdx|half|hdx|100half|100hdx> +# speed {10|100|1000} +# duplex {half|full} +# auto {on|off} +# slave <if> ... +# modprobe [module [module_options]] +# lladdr <mac_addr> +# mtu <mtu> +# [no] arp +# [no] multicast +# shutdown +# ip route <ip/mask> <gw> + +. `dirname $0`/functions + +option ip option_ip +option media standard_option +option duplex standard_option +option speed standard_option +option auto standard_option +option slave multiple_option +option modprobe multiple_option +option lladdr standard_option +option mtu standard_option +option arp boolean_option 1 +option multicast boolean_option 1 +option shutdown boolean_option + +SVC_VARS="addr_list route_list addr_idx route_idx" + +# changes the negociation parameters for interface $1 +# usage: set_media <interface> <media> +function set_media { + case "$2" in + auto) + /sbin/mii-diag -r $1 >/dev/null 2>&1 || \ + /sbin/ethtool -s $1 autoneg on + ;; + full|fdx|100full|100fdx) + /sbin/mii-diag -F 100baseTx-FD $1 >/dev/null 2>&1 || \ + /sbin/ethtool -s $1 speed 100 duplex full autoneg off + ;; + half|hdx|100half|100hdx) + /sbin/mii-diag -F 100baseTx-HD $1 >/dev/null 2>&1 || \ + /sbin/ethtool -s $1 speed 100 duplex half autoneg off + ;; + *) /sbin/mii-diag -F $opt_media $1 >/dev/null ;; + esac +} + +# changes the negociation parameters for interface $1 +# $2=speed(10|100|1000) or "" if unchanged +# $3=duplex(half|full) or "" if unchanged +# $4=auto(on|off) or "" if unchanged +function set_media2 { + local miistr + if [ "$4" = "on" ]; then + /sbin/mii-diag -r $1 >/dev/null 2>&1 || \ + /sbin/ethtool -s $1 autoneg on + fi + + [ "$3" = "half" ] && miistr="HD" || miistr="FD" + if [ "$2" = "10" ]; then + miistr=10baseT-$miistr + else + miistr=${2:-100}baseTx-$miistr + fi + + /sbin/mii-diag -F $miistr $1 >/dev/null 2>&1 || \ + /sbin/ethtool -s $1 ${2:+speed $2} ${3:+duplex $3} +} + +function fct_begin_section { + addr_list=( ) + route_list=( ) + addr_idx=0 + route_idx=0 +} + +# usage: ip <ip> {addr|route} ... +function option_ip { + shift + local cmd=$1 + shift + case "$cmd" in + addr|address) + addr_list[$addr_idx]="$*" + addr_idx=$[$addr_idx+1] + ;; + route) + route_list[$route_idx]="$*" + route_idx=$[$route_idx+1] + ;; + dhcp) + addr_list[$addr_idx]="dhcp" + addr_idx=$[$addr_idx+1] + ;; + --disable) + ;; + *) + echo "Unknown ip command : $cmd $*" + return 1 + esac +} + +function do_start { + local svcname=$1 + local instname=$2 + local arg + + if [ -z "$instname" ]; then + echo "# Starting $svcname ..." + #if [ "$opt_modprobe" != "#" ]; then + # modprobe $opt_modprobe || return 1 + #fi + arg=0 + while [ $arg -lt ${#opt_modprobe[*]} ]; do + if [ "${opt_modprobe[$arg]}" != "#" ]; then + modprobe ${opt_modprobe[$arg]} || return 1 + fi + arg=$[$arg+1] + done + arg=0 + while [ $arg -lt $route_idx ]; do + local dest gw + dest=${route_list[$arg]%%[ ]*} + gw=${route_list[$arg]##*[ ]} + ip route add $dest via $gw + arg=$[$arg+1] + done + echo " ==> start $svcname : Done." + return $? + fi + + if [ "$opt_shutdown" = 1 ]; then + return 0 + fi + + echo "# Starting $svcname${instname:+[$instname]} ..." + # we only check running instances when an interface is defined + do_status $svcname $instname > /dev/null 2>&1 + if [ $? = 0 -a $FORCE_START_STOP -eq 0 ] ; then + echo " ==> Service $svcname${instname:+[$instname]} already running."; + [ $SVC_AUTO_START -eq 0 ] && echo " ==> please use '--force' or 'restart' instead or check with 'status'." + return 0 + fi + + arg=0 + while [ $arg -lt ${#opt_modprobe[*]} ]; do + if [ "${opt_modprobe[$arg]}" != "#" ]; then + if ! modprobe ${opt_modprobe[$arg]}; then + echo " ==> start $svcname${instname:+[$instname]} : modprobe ${opt_modprobe[$arg]} Failed." + return 1 + fi + else + local err # do not merge the assignment here, local sets $? to 0 ! + err=`modprobe $instname 2>&1` + if [ $? -gt 0 ]; then + if ! grep -q "^[ ]*$instname:" /proc/net/dev >/dev/null 2>&1; then + echo " ==> modprobe $instname failed : $err" + return 1 + fi + fi + fi + arg=$[$arg+1] + done + + ip addr flush dev $instname >/dev/null 2>&1 + ip link set $instname down >/dev/null 2>&1 + + if [ "$opt_media" ]; then + if [ -n "$opt_speed" -o -n "$opt_duplex" -o -n "$opt_auto" ]; then + echo " ==> Warning: option 'media' inhibits 'speed','duplex' and 'auto'." + fi + set_media $instname "$opt_media" + echo " ==> Link set to $opt_media for interface $instname" + elif [ -n "$opt_speed" -o -n "$opt_duplex" -o -n "$opt_auto" ]; then + set_media2 $instname "${opt_speed:--}" "${opt_duplex:--}" "${opt_auto:--}" + echo " ==> Link configuration changed for interface $instname" + fi + + if [ "$opt_lladdr" ]; then + ip link set $instname address $opt_lladdr + fi + + if [ "$opt_mtu" ]; then + ip link set $instname mtu $opt_mtu + fi + + if [ "$opt_multicast" != 1 ]; then + ip link set $instname multicast off + #else + #ip link set $instname multicast on + fi + + if [ "$opt_arp" != 1 ]; then + ip link set $instname arp off + fi + + if ! ip link set $instname up; then + echo " ==> start $svcname${instname:+[$instname]} : Failed." + return 1 + fi + if [ ${#opt_slave[*]} -gt 0 ]; then + for arg in ${opt_slave[*]}; do + if ! $PFULLNAME status $arg >/dev/null 2>&1; then + echo " ==> FAILED! need to start slave $arg before $instname" + else + ifenslave $instname $arg >/dev/null 2>&1 + ip addr flush dev $arg >/dev/null 2>&1 + fi + done + fi + + arg=0 + while [ $arg -lt $addr_idx ]; do + if [ "${addr_list[$arg]}" = "dhcp" ]; then + echo " ==> Waiting for ip address with DHCP request ... " + dhcpcd -t 10 $instname + else + ip addr add ${addr_list[$arg]} dev $instname + fi + arg=$[$arg+1] + done + + arg=0 + while [ $arg -lt $route_idx ]; do + local dest gw + dest=${route_list[$arg]%%[ ]*} + gw=${route_list[$arg]##*[ ]} + ip route add $dest via $gw dev $instname + arg=$[$arg+1] + done + echo " ==> start $svcname${instname:+[$instname]} : Done." +} + +function do_status { + local instname=$2 + if [ "$instname" ]; then + if ip link show $instname | grep -q UP; then + echo "Interface $instname is up." + return 0 + else + echo "Interface $instname is down." + return 1 + fi + #else + # if ip route list | grep -q dev; then + # echo "Network is up." + # return 0 + # else + # echo "Network is down." + # return 1 + # fi + fi + REPLY= + return 0 +} + + +function do_stop { + local svcname=$1 + local instname=$2 + local arg + + if [ -z "$instname" ]; then + echo "# Stopping $svcname ..." + arg=${#opt_modprobe[*]} + while [ $arg -gt 0 ]; do + arg=$[$arg-1] + if [ "${opt_modprobe[$arg]}" != "#" ]; then + rmmod -r ${opt_modprobe[$arg]} >/dev/null 2>&1 + fi + done + + arg=0 + while [ $arg -lt $route_idx ]; do + ip route del ${route_list[$arg]} >/dev/null 2>&1 + arg=$[$arg+1] + done + return $? + fi + + echo "# Stopping $svcname${instname:+[$instname]} ..." + + if ! do_status $svcname $instname > /dev/null 2>&1; then + echo " ==> stop $svcname${instname:+[$instname]} : already stopped." + return 0 + fi + + # we may have to kill dhcpcd + arg=0 + while [ $arg -lt $addr_idx ]; do + if [ "${addr_list[$arg]}" = "dhcp" ]; then + local proc + for proc in $(svc_pidof dhcpcd) ; do + if grep -qs $instname /proc/$proc/cmdline ; then kill $proc ; fi + done + fi + arg=$[$arg+1] + done + + ip addr flush dev $instname >/dev/null 2>&1 + ip link set $instname down >/dev/null 2>&1 + + arg=${#opt_modprobe[*]} + while [ $arg -gt 0 ]; do + arg=$[$arg-1] + if [ "${opt_modprobe[$arg]}" != "#" ]; then + rmmod -r ${opt_modprobe[$arg]} >/dev/null 2>&1 + else + rmmod -r $instname >/dev/null 2>&1 + fi + done + echo " ==> stop $svcname${instname:+[$instname]} : Done." +} + +#### these are the old versions. The slave mechanism should be checked. + +_start_if() { + local eth=$1 + local temp=`eval echo \\$int_${eth}_modprobe` + ip link show $eth >/dev/null 2>&1 + if [ "$temp" -a $? -ne 0 ] ; then + if [ "$temp" = modprobe ] ; then + modprobe $eth + else + modprobe $temp + fi + fi + + ip link show $eth | grep -q UP + if [ $? = 0 ] ; then + echo "Interface $eth already configured" + continue + fi + + if [ "`eval echo \\$int_${eth}_slave`" ]; then + # the slaves should be up before continuing + for int in `eval echo \\$int_${eth}_slave`; do + start_if $int + done + fi + + if [ "`eval echo \\$int_${eth}_media`" ]; then + media=`eval echo \\$int_${eth}_media` + case "$media" in + auto) /sbin/mii-diag -r $eth >/dev/null ;; + full|fdx|100full|100fdx) /sbin/mii-diag -F 100baseTx-FD $eth >/dev/null ;; + half|hdx|100half|100hdx) /sbin/mii-diag -F 100baseTx-HD $eth >/dev/null ;; + *) /sbin/mii-diag -F $media $eth >/dev/null ;; + esac + echo "Link set to $media for interface $eth" + fi + + ip link set $eth up + ip addr flush dev $eth >/dev/null 2>&1 + if [ "`eval echo \\$ip_dhcp_$eth`" = enable ] ; then + echo "Waiting for ip address with DHCP request ... " + dhcpcd -t 10 $eth + elif [ "`eval echo \\$ip_address_$eth`" ]; then + ip_address=`eval echo \\$ip_address_$eth` + ip_address_sec=`eval echo \\$ip_address_sec_$eth` + echo "Setting ip address $ip_address to interface $eth" + ip addr add $ip_address dev $eth + for addr in $ip_address_sec ; do + echo "Setting secondary ip address $addr to interface $eth" + ip addr add $addr dev $eth + done + fi + + if [ "`eval echo \\$int_${eth}_slave`" ]; then + ifenslave $eth `eval echo \\$int_${eth}_slave` + # we prefer no ip address on the slaves + for int in `eval echo \\$int_${eth}_slave`; do + ip addr flush dev $int + done + fi + + addr=`ip addr show $eth | grep "inet " | sed 's/^.*inet \([^ ]\+\) .*$/\1/'` + if [ ! -z "$addr" ]; then + if [ ! -z "$display_addr_in_issue" ]; then + echo " -> $eth has address $addr" + echo "$eth has address $addr" >> /etc/issue + fi + else + if [ ! -z "$display_addr_in_issue" ]; then + echo " -> $eth has no address" + echo "$eth has no address" >> /etc/issue + fi + fi +} + +_do_start() +{ + # set hostname + if [ "$hostname" ] ; then + echo "Setting hostname '$hostname'" + hostname $hostname + domainname `echo $hostname | cut -f2- -d.` + fi + + # set ip address for each interface + for eth in `set|grep -a '^int_[a-zA-Z0-9:-_]*=enable$'|\ + sed -e 's/.*_\(.*\)=.*/\1/'` ; do + start_if $eth + done + + # set ip route + for route in `echo $ip_route` ; do + way=`echo $route | cut -f1 -d:` + if [ -z "$way" ] ; then way=default ; fi + gateway=`echo $route | cut -f2 -d":"` + echo "Setting route $way via $gateway" + /sbin/ip route add $way via $gateway + done +} + +_do_stop() +{ + for eth in `set|grep -a '^int_[a-zA-Z0-9:-_]*=enable$'|\ + sed -e 's/.*_\(.*\)=.*/\1/'` ; do + echo "Shutting down $eth" + if [ "`eval echo \\$ip_dhcp_$eth`" = enable ] ; then + for proc in `pidof dhcpcd` ; do + if grep -qs $eth /proc/$proc/cmdline ; then kill $proc ; fi + done + fi + ip addr flush dev $eth >/dev/null 2>&1 + ip link set $eth down + if [ ! -z `eval echo \\$int_"$eth"_slave` ]; then + for slave in `eval echo \\$int_"$eth"_slave`; do + ip link set $slave down arp on + ip addr flush dev $slave >/dev/null 2>&1 + done + fi + if [ ! -z "$display_addr_in_issue" ]; then + grep -v "$eth " /etc/issue > /etc/issue- && mv /etc/issue- /etc/issue + fi + done +} + +_do_status() +{ + echo "'ip addr show' give:" + ip addr show + echo "'ip route show' give:" + ip route show +} + +load_config + + diff --git a/sbin/init.d/ntp b/sbin/init.d/ntp new file mode 100755 index 0000000..3d18789 --- /dev/null +++ b/sbin/init.d/ntp @@ -0,0 +1,56 @@ +#!/bin/bash + +. `dirname $0`/functions + +option config standard_option /etc/ntp/ntp.conf +option keys standard_option /etc/ntp/ntp.keys +option pidfile reserved_option /var/run/ntp.pid +option hard_sync boolean_option +option force_sync boolean_option +option sync_servers long_option + +option procname reserved_option ntpd +option bin reserved_option /usr/sbin/ntpd +option cmdline reserved_option '$bin -c $opt_config -p $pidfile -k $opt_keys' + +# assign values after all the options have been read +function fct_end_section { + if [ -z "$opt_sync_servers" ]; then + valueof $opt_config server > /dev/null + opt_sync_servers=$REPLY + fi +} + +# perform a forced synchronisation before starting the daemon +function fct_pre_start { + local driftfile + + valueof $opt_config driftfile > /dev/null 2>&1 ; driftfile=$REPLY + if [ -n "$driftfile" -a ! -e "${driftfile%/*}" ] ; then + mkdir -p ${driftfile%/*} + fi + if [ "$opt_force_sync" = "1" -a "$opt_sync_servers" ]; then + ntpdate -u -t 2 $opt_sync_servers + fi + if [ "$opt_hardsync" = "1" ]; then + /sbin/hwclock -w --noadjfile --localtime + fi +} + +# perform a forced synchronisation before stopping the daemon +function fct_pre_stop { + if [ "$opt_hardsync" = "1" ]; then + /sbin/hwclock -w --noadjfile --localtime + fi +} + +# execute a forced resynchronisation to sync servers +function do_update { + if [ "$opt_sync_servers" ]; then + ntpdate -t 2 -u $opt_sync_servers + /sbin/hwclock -w --noadjfile --localtime + fi +} + +load_config + diff --git a/sbin/init.d/pdnsd b/sbin/init.d/pdnsd new file mode 100755 index 0000000..9adeb55 --- /dev/null +++ b/sbin/init.d/pdnsd @@ -0,0 +1,16 @@ +#!/bin/bash + +. `dirname $0`/functions + +option config standard_option /etc/pdnsd.conf +option pidfile reserved_option /var/run/syslog-ng.pid + +option bin reserved_option /usr/sbin/pdnsd +option cmdline reserved_option '$bin -c $opt_config -d -p $pidfile' + +# perform a forced synchronisation before starting the daemon +function fct_pre_start { + if [ ! -d /var/cache/pdnsd ] ; then mkdir -p /var/cache/pdnsd ; fi +} + +load_config diff --git a/sbin/init.d/squid b/sbin/init.d/squid new file mode 100755 index 0000000..cdb32f1 --- /dev/null +++ b/sbin/init.d/squid @@ -0,0 +1,43 @@ +#!/bin/bash + +. `dirname $0`/functions + +option config standard_option /etc/opt/squid/squid.conf +option httpport standard_option +option icpport standard_option +option usesyslog boolean_option 0 +option createswap boolean_option 0 +option catchsignals boolean_option 1 +option dnstest boolean_option 1 +option waitrebuild boolean_option 0 +option reuseaddr boolean_option 1 +option doublecheck boolean_option 0 +option vhostaccel boolean_option 0 +option bin reserved_option /opt/sbin/squid + +function fct_end_section { + local chroot + # try to find pidfile from the config file if unspecified + if [ -z "$pidfile" ]; then + valueof ${opt_config:-/etc/opt/squid/squid.conf} chroot >/dev/null 2>&1 + chroot=$REPLY + valueof ${opt_config:-/etc/opt/squid/squid.conf} pid_filename >/dev/null 2>&1 + pidfile=$chroot/${REPLY:-/var/log/squid.pid} + pidfile=${pidfile//\/\//\/} # clear double slashes + fi + + # let's add the options to the command line + cmdline="$cmdline ${opt_config:+-f $opt_config} ${opt_httpport:+-a $opt_httpport}" + cmdline="$cmdline ${opt_icpport:+-u $opt_icpport}" + [ "$opt_usesyslog" = "1" ] && cmdline="$cmdline -s" + [ "$opt_createswap" = "1" ] && cmdline="$cmdline -z" + [ "$opt_catchsignals" != "1" ] && cmdline="$cmdline -C" + [ "$opt_dnstest" != "1" ] && cmdline="$cmdline -D" + [ "$opt_reuseaddr" != "1" ] && cmdline="$cmdline -R" + [ "$opt_waitrebuild" = "1" ] && cmdline="$cmdline -F" + [ "$opt_doublecheck" = "1" ] && cmdline="$cmdline -S" + [ "$opt_vhostaccel" = "1" ] && cmdline="$cmdline -V" +} + +load_config + diff --git a/sbin/init.d/sshd b/sbin/init.d/sshd new file mode 100755 index 0000000..deb5e86 --- /dev/null +++ b/sbin/init.d/sshd @@ -0,0 +1,103 @@ +#!/bin/bash + +. `dirname $0`/functions + +STOP_FIRST_WITH=KILL + +option bin reserved_option /usr/sbin/sshd +option cmdline reserved_option '$bin ${opt_port:+-p $opt_port} ${opt_config:+-f $opt_config} ${opt_protocol:+-oProtocol=$opt_protocol} ${opt_listen:+-oListenAddress=$opt_listen} ${pidfile:+-oPidfile=$pidfile}' +option port standard_option +option config standard_option +option protocol standard_option +option listen standard_option +option pidfile reserved_option /var/run/sshd.pid + +sshd_cfgfile="" + +# assign default values to options and variables before parsing the cfg file +function fct_end_section { + sshd_cfgfile=${opt_config:-/etc/ssh/sshd_config} + valueof $sshd_cfgfile HostKey > /dev/null + hostkey_list=$REPLY + valueof $sshd_cfgfile PidFile > /dev/null ; pidfile=${REPLY:-$pidfile} +} + +function sshd_find_keys { + if [ -z "$hostkey_list" ]; then + echo " File $sshd_cfgfile references no key." + if [ -z "$opt_protocol" -o "${opt_protocol/1//}" != "$opt_protocol" ]; then + echo " Assuming /etc/ssh/ssh_host_key for Protocol v1." + hostkey_list="$hostkey_list /etc/ssh/ssh_host_key" + fi + if [ -z "$opt_protocol" -o "${opt_protocol/2//}" != "${opt_protocol}" ] + then + echo " Assuming /etc/ssh/ssh_host_rsa_key for Protocol v2." + hostkey_list="$hostkey_list /etc/ssh/ssh_host_rsa_key" + echo " Assuming /etc/ssh/ssh_host_dsa_key for Protocol v2." + hostkey_list="$hostkey_list /etc/ssh/ssh_host_dsa_key" + fi + else + echo " File $sshd_cfgfile references these keys : $hostkey_list" + fi +} + +function fct_pre_start { + local missing=0 + local key + local must_remount_ro=0 + + sshd_find_keys + for key in $hostkey_list; do + if [ ! -e "$key" ]; then + echo " Warning! host key $key does not exist." + missing=$[$missing+1] + fi + done + + if [ "$missing" -gt "0" ]; then + echo " Trying to generate the keys before starting SSHD." + remount_rw /etc && must_remount_ro=1 + do_install + [ $must_remount_ro -eq 1 ] && remount_ro /etc + echo " Now starting SSHD." + fi +} + +# This ensures that we use --force to restart the service +function do_restart { + do_stop $* + FORCE_START_STOP=1 + do_start $* +} + +function do_install { + local type="" + local key + + sshd_find_keys + for key in $hostkey_list; do + if [ ! -e "$key" ]; then + case "$key" in + */ssh_host_key*) type=rsa1 ;; + */ssh_host_rsa_key*) type=rsa ;; + */ssh_host_dsa_key*) type=dsa ;; + *) type="" + echo " Warning! host key $key does not exist and cannot" + echo " be auto-generated since it does not have a standard name." + echo " If SSHD doesn't start, you'll have to generate it manually this way :" + echo " # ssh-keygen -t { rsa1 | rsa | dsa } -N '' -f $key" + echo + ;; + esac + if [ "$type" ]; then + ssh-keygen -t $type -N '' -f $key + if [ ! -e "$key" ]; then + echo " ERROR : ssh-keygen could not generate $type host key $key" + fi + fi + fi + done +} + +load_config + diff --git a/sbin/init.d/stat b/sbin/init.d/stat new file mode 100755 index 0000000..b049145 --- /dev/null +++ b/sbin/init.d/stat @@ -0,0 +1,105 @@ +#!/bin/bash + +. `dirname $0`/functions + +option output standard_option +option runas standard_option stat +option opt long_option +option freq standard_option +option method standard_option +option statusfile standard_option +option check_interval reserved_option 60 +option bin reserved_option /opt/exosec/bin/statistics + +function fct_begin_section { + # assign the default instance name from the config file argument + pidfile=/var/run/stat/$2.pid + procname=statistics + opt_statusfile=/var/run/stat/$2.nfo + opt_output=/var/run/stat/$2.log +} + +function do_start { + local p=$1 ; shift + local testname=$1 + local message + + opt_method=${opt_method:-$testname} + if [ "$FORCE_START_STOP" -eq 0 ] && do_status $p $testname > /dev/null ; then + echo "Already started, stop it before restarting" + return 1 + fi + + message="# Starting Monitoring on $testname for $testname statistics ..." + echo "$message" + + { local path + for path in `dirname $pidfile` `dirname $opt_statusfile` `dirname $opt_output`; do + mkdir -p $path 2> /dev/null && \ + { [ -z "$opt_runas" ] || chown $opt_runas $path && chmod 700 $path ; } \ + || { echo "Bad owner or rights on directory $path ($opt_runas:700), fix it." + return 1 ; } + done ; + } + + # note: here, cmdline doesn't include $bin. + cmdline="-t $opt_method -o $opt_output -s $opt_statusfile -p $pidfile + -w $opt_freq -n $testname $opt_opt" + + if [ -z "$opt_runas" ] ; then + ( $bin $cmdline ) + else + ( su - $opt_runas -- $cmdline ) + fi + + if [ "$?" = 0 ] ; then + echo "$message done." + else + echo "$message error." + fi +} + +function do_check { + local run_stat date status service result next_stat + local service=$1 instance=$2 + + if do_status $service $instance > /dev/null ; then + run_stat=RUNNING + uptime=$[ $( date +%s ) - $( date -d "$( ps ho lstart $REPLY)" +%s ) ] + else + run_stat=STOPPED + uptime=0 + fi + if [ ! -e $opt_statusfile ] ; then + echo "$HOSTNAME $service.$instance $(date +%s) STOPPED" + return 1 + fi + + read idsvc date status result < $opt_statusfile > /dev/null 2>&1 + if [ $? != 0 ] ; then + echo "$HOSTNAME $2 $(date +%s) STOPPED" ; return 1 + fi + + diff=$[ $(date +%s) - $date ] + [ $[ $diff > 2 * $opt_freq ] = 1 -a $status = OK ] && + status="ALERT" + [ $[ $diff > $opt_freq ] = 1 -a $status = OK ] && + status="WARNING" + + if [ $run_stat = RUNNING ] ; then + read pid < $pidfile + set -- $( ps ahxo ppid,pid,comm,lstart | \ + awk '{if ($1 == '$pid' && $3 == "sleep") print $0 } ') + if [ $# == 0 ] ; then + status=$status,$opt_freq + else + pid=$2 ; shift 3 ; start=$( date -d "$*" +%s) + next_stat=$[ $opt_freq - $(date +%s) + $start ] + status=$status,$next_stat + fi + fi + + echo "$HOSTNAME $service.$instance $date $run_stat $uptime $status $result" +} + +load_config diff --git a/sbin/init.d/sysprofiles b/sbin/init.d/sysprofiles new file mode 100755 index 0000000..279215a --- /dev/null +++ b/sbin/init.d/sysprofiles @@ -0,0 +1,3 @@ +#!/bin/bash +cfgfile=$1 +. /sbin/init.d/functions -f $cfgfile --list_sections|(last=;while read svc rest; do if [ "$svc" != "$last" ]; then /sbin/init.d/$svc -f $cfgfile --auto start; fi; last=$svc; done) diff --git a/sbin/init.d/system b/sbin/init.d/system new file mode 100755 index 0000000..46640b5 --- /dev/null +++ b/sbin/init.d/system @@ -0,0 +1,76 @@ +#!/bin/bash + +. `dirname $0`/functions + +option hostname standard_option +option modprobe multiple_option +option sysctl multiple_option +option file_max standard_option + +function do_start { + local svcname=$1 + local instname=$2 + local arg + + arg=0 + while [ $arg -lt ${#opt_modprobe[*]} ]; do + modprobe ${opt_modprobe[$arg]} || return 1 + arg=$[$arg+1] + done + + if [ "$opt_file_max" ]; then + echo $opt_file_max > /proc/sys/fs/file-max + fi + + if [ "$opt_hostname" ] ; then + echo "Setting hostname '$opt_hostname'" + echo ${opt_hostname%%.*} >/proc/sys/kernel/hostname + echo ${opt_hostname#*.} >/proc/sys/kernel/domainname + fi + + for arg in ${opt_sysctl[*]}; do + local sysctl value + sysctl=${arg%%=*} + sysctl=${sysctl//.//} + value=${arg##*=} + if [ -e "/proc/sys/$sysctl" ]; then + echo $value > /proc/sys/$sysctl + else + echo "Non-existent sysctl entry : $arg" + fi + done + return 0 +} + +function do_status { + local instname=$2 + echo "System status :" + echo -n "Hostname : "; hostname + echo "Modules list :"; lsmod + return 0 +} + + +function do_stop { + local svcname=$1 + local instname=$2 + + arg=${#opt_modprobe[*]} + while [ $arg -gt 0 ]; do + arg=$[$arg-1] + rmmod -r ${opt_modprobe[$arg]} >/dev/null 2>&1 + done + + return 0 +} + +function do_check { + local svcname=$1 + local instname=$2 + + read uptime idletime < /proc/uptime + echo "$HOSTNAME $svcname.$instname $(date +%s) RUNNING ${uptime%%.*} OK" +} + +load_config + diff --git a/sbin/init.d/thttpd b/sbin/init.d/thttpd new file mode 100755 index 0000000..091648b --- /dev/null +++ b/sbin/init.d/thttpd @@ -0,0 +1,27 @@ +#!/bin/bash + +. `dirname $0`/functions + +option config standard_option +option port standard_option 80 +option docroot standard_option /var/www +option chroot boolean_option 1 +option symlink boolean_option 1 +option user standard_option +option address standard_option +option logfile standard_option +option charset standard_option iso-8859-1 +option bin reserved_option /usr/sbin/thttpd + +# assign default values to options and variables before parsing the cfg file +function fct_begin_section { + pidfile="/var/run/thttpd-$2.pid" + cmdline='$bin ${opt_config:+-C $opt_config} ${opt_port:+-p $opt_port} + ${opt_docroot:+-d $opt_docroot} ${opt_chroot:+-r} ${opt_symlink:+-s} + ${opt_user:+-u $opt_user} ${opt_address:+-h $opt_address} + ${opt_logfile:+-l $opt_logfile} ${opt_charset:+-T $opt_charset} + ${pidfile:+-i $pidfile}' +} + +load_config + diff --git a/sbin/initscript b/sbin/initscript new file mode 100755 index 0000000..678ae46 --- /dev/null +++ b/sbin/initscript @@ -0,0 +1,10 @@ +#!/bin/sh + +umask 022 +PATH=/bin:/sbin:/usr/sbin:/usr/bin +export PATH + +BOOTID=`cat /proc/sys/kernel/random/boot_id` +export BOOTID + +eval exec "$4" diff --git a/sbin/rc.0 b/sbin/rc.0 new file mode 100755 index 0000000..fb546de --- /dev/null +++ b/sbin/rc.0 @@ -0,0 +1,83 @@ +#! /bin/sh +# +# rc.6 This file is executed by init when it goes into runlevel +# 0 (halt) or runlevel 6 (reboot). It kills all processes, +# unmounts file systems and then either halts or reboots. +# +# Version: @(#)/etc/rc.d/rc.6 1.50 1994-01-15 +# +# Author: Miquel van Smoorenburg <miquels@drinkel.nl.mugnet.org> +# Modified by: Patrick J. Volkerding, <volkerdi@ftp.cdrom.com> +# + +# Set the path. +PATH=/sbin:/etc:/bin:/usr/bin:/usr/sbin + +# If there are SystemV init scripts for this runlevel, run them. +if [ -x /sbin/init.d/sysvinit ]; then + /sbin/init.d/sysvinit start +fi + +# Set linefeed mode to avoid staircase effect. +stty onlcr + +echo "Running shutdown script $0:" + +# Find out how we were called. +case "$0" in + *0) + command="halt" + ;; + *6) + command=reboot + ;; + *) + echo "$0: call me as \"rc.0\" or \"rc.6\" please!" + exit 1 + ;; +esac + +# Kill all processes. +# INIT is supposed to handle this entirely now, but this didn't always +# work correctly without this second pass at killing off the processes. +# Since INIT already notified the user that processes were being killed, +# we'll avoid echoing this info this time around. +if [ "$1" != "fast" ]; then # shutdown did not already kill all processes + killall5 -15 + sleep 5 + killall5 -9 +fi + +# Before unmounting file systems write a reboot or halt record to wtmp. +$command -w + +# Syncing data +sync + +# Unmount any remote filesystems: +echo "Unmounting remote filesystems." +umount -na -tnfs + +# Turn off swap, then unmount local file systems. +echo "Turning off swap." +swapoff -a +echo "Unmounting local file systems." +# Don't remount UMSDOS root volumes: +if [ ! "`cat /proc/mounts | head -1 | cut -d ' ' -f 5`" = "umsdos" ]; then + umount -na -t nonfs -t noproc + echo "Remounting root filesystem read-only." + mount -n -o remount,ro / +else + umount -na -t nonfs -t noumsdos -t noproc +fi +# This never hurts: +sync + +# Now halt (poweroff with APM kernels) or reboot. +if [ "$command" = "reboot" ]; then + echo "Rebooting." + reboot -f +else + halt -f -p +fi + diff --git a/sbin/rc.6 b/sbin/rc.6 new file mode 120000 index 0000000..120189f --- /dev/null +++ b/sbin/rc.6 @@ -0,0 +1 @@ +rc.0
\ No newline at end of file diff --git a/sbin/rc.K b/sbin/rc.K new file mode 100755 index 0000000..5150594 --- /dev/null +++ b/sbin/rc.K @@ -0,0 +1,41 @@ +#! /bin/sh +# +# rc.K This file is executed by init when it goes into runlevel +# 1, which is the administrative state. It kills all +# deamons and then puts the system into single user mode. +# Note that the file systems are kept mounted. +# +# Version: @(#)/etc/rc.d/rc.K 1.50 1994-01-18 +# Version: @(#)/etc/rc.d/rc.K 1.60 1995-10-02 (PV) +# +# Author: Miquel van Smoorenburg <miquels@drinkel.nl.mugnet.org> +# Modified by: Patrick J. Volkerding <volkerdi@ftp.cdrom.com> +# Modified by: Benoit Dolez <bdolez@meta-x.org> +# + +function loop { + echo + for i in 0 1 2 3 4 5 ; do echo -n . ; done + echo +} + +# Set the path. +PATH=/sbin:/etc:/bin:/usr/bin + +# If there are SystemV init scripts for this runlevel, run them. +if [ -x /sbin/init.d/sysvinit ]; then + /sbin/init.d/sysvinit start +fi + +# Kill all processes. +killall5 -1 +loop +killall5 -15 +loop +killall5 -9 +loop + +# Now go to the single user level +echo "Going to single user mode..." +telinit -t 1 1 + diff --git a/sbin/rc.M b/sbin/rc.M new file mode 100755 index 0000000..dc46e11 --- /dev/null +++ b/sbin/rc.M @@ -0,0 +1,70 @@ +#!/bin/sh + +if [ ! -x /bin/lcdwrite ] ; then function lcdwrite { /bin/true; } ; fi +if [ ! -x /bin/lcdtee ] ; then function lcdtee { /bin/cat; } ; fi + +LOG=/var/log/bootlog + +function start { + for service in $* ; do + echo -n "Starting $service ... " + echo -n "$service ... " | lcdwrite + echo "----- Starting $service with /sbin/init.d/$service -----" >> $LOG + if [ -x /sbin/init.d/$service ] ; then + /sbin/init.d/$service start >> $LOG 2>&1 + if [ $? -eq 0 ] ; then + echo "done" | lcdtee + echo "----- Done -----" >> $LOG + else + echo "failed" | lcdtee + echo "----- Failed -----" >> $LOG + fi + else + echo "failed" | lcdtee + echo "----- Failed -----" >> $LOG + fi + done +} + + +# Reinit /var/log/bootlog file +/bin/rm -rf /var/log/bootlog + +# Running multiuser part +echo "Starting Multi-user (`date`)" | tee -a $LOG + +# Enable loopback +ip link set dev lo up +ip addr add 127.0.0.1/8 dev lo + +# Cron should be moved to a proper service script + +# Starting 'crond' if exist +#if [ -x /usr/sbin/crond ] ; then +# if [ ! -d /var/spool/cron/crontabs ] ; then mkdir -p /var/spool/cron/crontabs ; fi +# crond +#fi + +# Starting 'atd' if exist +#if [ -x /usr/sbin/atd ] ; then +# atd +#fi + +# Sourcing base configuration +if [ -x /etc/startup.rc ] ; then + /etc/startup.rc | tee -a $LOG +elif [ -d /etc/startup.rc ] ; then + for i in /etc/startup.rc/S* ; do + $i + done +else + echo "No /etc/startup.rc file" | lcdwrite | tee -a $LOG + echo "No configuration file (/etc/startup.rc)" | tee -a $LOG +fi + +# Starting SystemV like daemon +if [ -d /etc/rc$RUNLEVEL.d -a -x /sbin/init.d/sysvinit ] ; then + /sbin/init.d/sysvinit start | tee -a $LOG +fi + +# OK diff --git a/sbin/rc.S b/sbin/rc.S new file mode 100755 index 0000000..4aa002d --- /dev/null +++ b/sbin/rc.S @@ -0,0 +1,178 @@ +#!/bin/sh + +umask 022 +export PATH=/sbin:/bin:/usr/sbin:/usr/bin + +# enable swapping +/sbin/swapon -a + +# initialize LCD if present +if [ ! -x /bin/lcdwrite ] ; then function lcdwrite { /bin/true; } ; fi +if [ ! -x /bin/lcdtee ] ; then function lcdtee { /bin/cat; } ; fi +echo | lcdwrite + +if [ ! -e /proc/mounts ] ; then + # mounting /proc device + mount -vnt proc /proc /proc +fi + +# be careful, we suppose that /dev was created by preinit program +# to be read-write + +if [ ! -d /dev/pts -a -w /dev/ ] ; then + # create /dev/pts + mkdir /dev/pts +fi + +# Create /dev/root if it doesn't exist +if [ ! -e /dev/root ] ; then + if grep -q " root=" /proc/cmdline ; then + set `sed -e "s/^.* root=\([^ ]\+\).*/\1/" < /proc/cmdline` + ln -s $1 /dev/root + fi +fi + +# Check the integrity of / filesystem except if it's a ramdisk +# major=`ls -l /dev/root|sed -e 's/^\(.*\)\([0-9]\+\)\(, .*\)$/\2/'` +# if [ "$major" != "1" ]; then +# /sbin/e2fsck -n /dev/root +# fi + +# Create /dev/boot if it doesn't exist +if [ ! -e /dev/boot ] ; then + if grep -q " boot=" /proc/cmdline ; then + set `sed -e "s/^.* boot=\([^ ]\+\).*/\1/" < /proc/cmdline` + ln -s $1 /dev/boot + elif grep -q '[ ]/boot[ ]' /etc/fstab ; then + set `grep '[ ]/boot[ ]' /etc/fstab` + ln -s $1 /dev/boot + fi +fi + +# Check the integrity of all filesystems +/sbin/fsck -a -A -C -R + +if [ $? -gt 1 ] ; then + #echo "Error with fsck, run 'fsck -y -a'" + #PS1="(Repair filesystem) \#"; export PS1 + #sulogin + #echo "Unmounting file systems..." + #umount -a + #mount -n -o remount,ro / + #sync + #echo "Rebooting system..." + #sleep 2 + #reboot + #/bin/sh + echo "Error with fsck, run 'fsck -y -a'." + echo " => remounting ALL filesystems READ-ONLY !!!" + # mount file systems in fstab (and create an entry for /) + # but not NFS because TCP/IP is not yet configured + mount -rnat nonfs,noproc,notmpfs + mount -nat tmpfs +else + # mount file systems in fstab (and create an entry for /) + # but not NFS because TCP/IP is not yet configured + mount -nat nonfs,noproc +fi + + +# check whether /var is already mounted read-write. If not, we'll do +# it because it's unacceptable to work in read-only mode ! +if touch /var/.$BOOTID >/dev/null 2>&1; then + rm -f /var/.$BOOTID >/dev/null 2>&1 +else + echo "WARNING: Mounting /var as tmpfs !" + umount /var >/dev/null 2>&1 + mount -o mode=755 -t tmpfs /var /var +fi + +# Create /var directories if they don't exist +if [ ! -d /var/tmp ] ; then mkdir -m 1777 /var/tmp ; fi +if [ ! -d /var/run ] ; then mkdir /var/run ; fi +if [ ! -d /var/state ] ; then mkdir /var/state ; fi +if [ ! -d /var/lib ] ; then mkdir /var/lib ; fi +if [ ! -d /var/spool ] ; then mkdir /var/spool ; fi +if [ ! -d /var/log ] ; then mkdir /var/log ; chown root:log /var/log; chmod 2750 /var/log; fi +if [ ! -d /var/cache ] ; then mkdir /var/cache ; fi +if [ ! -d /var/empty ] ; then mkdir /var/empty ; chmod 500 /var/empty; fi +if [ ! -d /var/adm/. ] ; then ln -s log /var/adm ; fi + +sync + +# check whether /tmp is already mounted read-write. If not, we'll do +# it because it's unacceptable to work in read-only mode ! +if touch /tmp/.$BOOTID >/dev/null 2>&1; then + rm -f /tmp/.$BOOTID >/dev/null 2>&1 +else + echo "Mounting /tmp as tmpfs" + umount /tmp >/dev/null 2>&1 + mount -o mode=1777 -t tmpfs /tmp /tmp + if [ $? != 0 ]; then + echo "WARNING: could not mount /tmp as tmpfs." + if [ -L /tmp ]; then + echo " /tmp is a symlink to nowhere. Trying to fix its destination :" + (cd / && mkdir -vp `readlink /tmp`) + if [ $? -eq 0 ]; then + echo " => Success ! Now trying to mount /tmp again :" + else + echo " => Failed ! Trying to make /tmp a directory :" + (mv -v /tmp /tmp.old || rm -vf /tmp) && mkdir -v /tmp + if [ $? -eq 0 ]; then + echo " => Success ! Now trying to mount /tmp again :" + else + echo " => Failed ! Trying again by remounting / RW :" + mount -vwo remount / && (mv -v /tmp /tmp.old || rm -vf /tmp) && mkdir -v /tmp + mount -vo remount / + if [ ! -d /tmp ]; then + echo " => Failed ! The system may be unstable !!!" + else + echo " => Success ! you were lucky, but check if / has been correctly remounted !" + echo " => Now trying to mount /tmp again :" + fi + fi + fi + elif [ ! -d /tmp ]; then + echo " Trying to make /tmp a directory :" + (mv -v /tmp /tmp.old || rm -vf /tmp) && mkdir -v /tmp + if [ $? -eq 0 ]; then + echo " => Success ! Now trying to mount /tmp again :" + else + echo " => Failed ! Trying again by remounting / RW :" + mount -vwo remount / && (mv -v /tmp /tmp.old || rm -vf /tmp) && mkdir -v /tmp + mount -vo remount / + if [ ! -d /tmp ]; then + echo " => FAILED ! The system may be unstable !!!" + else + echo " => Success ! you were lucky, but check if / has been correctly remounted !" + echo " => Now trying to mount /tmp again :" + fi + fi + fi + + # either it was a directory, or it now is. + if [ -d /tmp ]; then + mount -o mode=1777 -t tmpfs /tmp /tmp && echo " => Success !" || echo " => FAILED ! /tmp is a directory but is unmountable !!! The system may be unstable" + fi + fi +fi + +/bin/rm -f /var/run/utmp /var/run/*.pid >/dev/null 2>&1 +/bin/rm -rf /tmp/* /tmp/.[^.]* /tmp/..?* >/dev/null 2>&1 +touch /var/log/wtmp /var/log/lastlog + +#if mkdir /tmp/.$BOOTID ; then +# dmesg > /tmp/.$BOOTID/dmesg +#fi + +# Writing Status +#for dir in / /dev /tmp /var /etc /boot ; do +# s="" +# if [ -L $dir ] ; then s=$s"a symbolic-link " ; t=L ; fi +# if [ -w $dir ] ; then s=$s"read-write "; t=RW ; else +# s=$s"read-only " ; t=RO ; fi +# echo "$dir is $s" +#done + +echo "Base system done." | lcdtee + |