#!/bin/sh # # (c) Copyright 2002, 2003, 2005 Stichting Wireless Leiden, all # rights reserved. More information can be found on # http://wwww.wirelessleiden.nl and the license is at: # http://wleiden.webweaving.org:8080/svn/node-config/LICENSE # # 1.00 # ?? Marten Vijn 24-03-03 # ?? new version 14-11-2003 # 1.03 proxy cleanup, detect faulty files, generalize # file list, check node name to be valid, '-n' mode. # make moving of final files a bit safer. (dirkx) # 1.04 Add auto read-only detection. (dirkx) # 1.05 Cope with WHOST containing a port number. (dirkx). # 1.06 Better diff (dirkx) # 1.07 Check versions of OS and Script # # If there is a global system configuration file, suck it in. # PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin TMPDIR=${TMPDIR:-/tmp} TMPPREFIX=${TMPDIR}/wl-tmp-$$ WHOST=${WHOST:-rambo.wleiden.net} HTTP_PROXY_DEFAULT=${HTTP_PROXY:-http://proxy.wleiden.net:3128} HTTP_USER_AGENT=${HTTP_USER_AGENT:-curl.faked.fetch/0.0} VERSION=1.07 QUIET=${QUIET:-} PRETEND=no FORCE=no CMD=do_move DLV=no # Genesis master location. link=${GENESIS:-http://${WHOST}/cgi-bin/g_list.pl/} list=filelist # Location for private config lcd=${LCDIR:-/lcd} dir=${lcd} FETCH=${FETCH:-/usr/bin/fetch} test -e ${FETCH} || FETCH="curl" if echo ${FETCH} | grep -q curl; then FETCH="${FETCH} --silent" else FETCH="${FETCH} -q" fi usage() { echo Usage $0 [-q] [-p proxy] [-d] [-D] [-n] [hostname] echo "-p Set a proxy" echo "-P Use ${HTTP_PROXY_DEFAULT} as a proxy" echo "-D Use DHCP to get an address" echo "-n Show what would happen - but do not do it" echo "-d Diff met hudiige config (maar doe niets)" echo "-q Suppress all output and user interaction" echo "-F Force disk to write" echo "-i Ignore all safety checks checks" exit 1 } for i in $* do case "$i" in -D) connset || exit 1 ;; -q) QUIET=yes ;; -i) DLV= ;; -d) CMD=do_diff dir=${TMPDIR} ;; -p) shift; HTTP_PROXY=$1 export HTTP_PROXY ;; -p) HTTP_PROXY=HTTP_PROXY_DEFAULT export HTTP_PROXY ;; -n) PRETEND=yes ;; -F) FORCE=yes ;; *) test $# -eq 1 || usage nodename=$i break; ;; esac shift done HOST=`echo ${WHOST} | sed -e 's/:.*//'` set `echo $VERSION | sed -e 's/\./ /'` VERSION_MAJOR=$1 VERSION_MINOR=$2 VERSION_OTHER=$3 # connection test function connset() { if [ `ps ax | grep -c dhclient` != "1" ] ; then killall dhclient fi echo "Enter an IP address of a nearby Nameserver or use:" echo " 1 to use COPE \(on Wleiden\)" echo " 2 to use XS4All \(on the internet\)" echo " 3 to use the LCP server \(on the internal LCP networ\)" echo -n "IP address or 1/2/3: " read dns_list case $dns_list in 1) resolver="172.17.8.1" ;; 2) resolver="194.109.9.99" ;; 3) resolver="10.0.0.1" ;; *) resolver=$dns_list ;; esac cp /etc/resolv.conf /etc/resolv.bak || exit 1 echo "nameserver ${resolver}" > /etc/resolv.conf for nic in `ifconfig -l` do case ${nic} in lo0 | wi*) ;; *) if ping -qnoc ${HOST}; then echo Connection on interface ${nic} to ${HOST} ok. else killall dhclient echo Trying to get a DHCP lease on ${nic} dhclient -1 ${nic} fi ;; esac done } log() { if [ -z ${QUIET} ]; then echo "$*" fi } lognlr() { if [ -z ${QUIET} ]; then echo -n "$*" fi } cleanse() { rm -f ${TMPPREFIX}.? } # Normal exit; but make sure # we also clean up any tmp files # cleanexit() { E=1 if [ $# -gt 0 ]; then E=$1 fi cleanse log Exit exit $E # Trap any weird exit codes. exit 1 } safefetch() { url=$1 file=$2 ${FETCH} -o - ${url} > ${TMPPREFIX}.x \ || cleanexit 1 # Genesis can provide us with corrupted/empty files # with a 200 OK - so insist that they are at least # a few lines long. # set `wc -l ${TMPPREFIX}.x` if [ $1 -lt 2 ]; then echo File ${link}${nodename} is less than 2 lines long. echo Assuming a problem with Genesis. cleanexit 2 fi cp ${TMPPREFIX}.x ${file} \ || cleanexit 1 rm -f ${TMPPREFIX}.x return 0 } getvalidnodenames() { log Fetching list of nodes from ${link} safefetch ${link} ${nlist} || cleanexit 1 } getvalidnodename() { while ! grep -q "^${nodename}\$" ${nlist} do echo Nodes: if [ -x /usr/bin/column ]; then column ${nlist} else cat ${nlist} fi echo echo -n enter nodename \[default: ${default}\]: if [ -z ${QUIET} ]; then read nodename else nodename=${default} fi if [ "x${nodename}" = "x" ]; then nodename=${default} fi done echo Node Selected: ${nodename} } do_diff() { if test -e $lcd/$1; then diff -uwbB $lcd/$1 $dir/$1.new else echo Warning: $lcd/$1 does not yet exist - no DIFF fi } do_move() { if [ -e $dir/$1 ]; then mv $dir/$1 $dir/$1.bak || cleanexit 1 fi cp $dir/$1.new $dir/$1 || cleanexit 1 rm $dir/$1.new || cleanexit 1 } linkin() { symdir=$1 file=$2 if [ ${PRETEND} = 'yes' ]; then echo "** $CMD $*" else $CMD $file || exit 1 fi test -e $symdir/$file || ( echo WARNING: Symlink $symdir/$file not in place. echo use: ln -s $dir/$file $symdir/$file echo to fix if appropriate. ) } log Config Node -- Version: $VERSION '$Rev: 5004 $' # Make sure we clean up our mess when needed. trap "rm -f ${TMPPREFIX}.?; echo Failed; exit 1;" 2 3 if [ ${PRETEND} != 'yes' -a ${CMD} != 'do_diff' ]; then if mount | grep "on / " | grep -q read-only; then if [ ${FORCE} = "yes" ]; then echo Forcing read-only disk into rw. fsck / || exit 2 mount -o noatime -u -w / || exit 2 || exit 1 trap "mount -u -r /; rm -f ${TMPPREFIX}.?; echo Failed; exit 1;" 2 3 FORCE=rw else echo ERROR - disk / is mounted read only. Aborting. exit 1 fi fi fi export HTTP_USER_AGENT export TMPDIR #check config dir # if [ ! -d ${dir} ]; then mkdir -p ${dir} || cleanexit 1 fi if [ -z ${HTTP_PROXY} ]; then ( log Checking DNS for ${HOST} host ${HOST} > /dev/null || exit 1 log Checking if ${HOST} can be reached ping -qnoc 1 ${HOST} > /dev/null || exit 1 log Connection: Ok exit 0 ) || connset else log Connection not checked because there is an http proxy configured: ${HTTP_PROXY}. fi if [ -r ${lcd}/myname ]; then default=`cat ${lcd}/myname` else default=`hostname -s` test -z $default && default=none fi if [ ! -z ${QUIET} ]; then if [ -z ${nodename} ]; then nodename=${default} fi fi nlist=${TMPPREFIX}.l test -z $default && default=$nodename getvalidnodenames || exit 1 test -z $nodename && getvalidnodename while test -z $nodename || ! grep -q ${nodename} ${nlist} do echo echo Error: Node named \"$nodename\" not known. if [ -z ${QUIET} ]; then exit 1 fi echo Please select one from the list. echo getvalidnodename done lognlr "Checking release and OS versions: " safefetch ${link}${nodename}/info $dir/info.last \ || cleanexit 1 OS=`uname -s` REL=`uname -r` set -- `head -1 $dir/info.last` # FreeBSD 5.0-RELEASE 1 YES if [ $# != 4 ]; then echo Info verification failed. cleanexit 1 fi if [ x$4 != 'xYES' ]; then echo Genesis marked as disabled for this machine. test -z ${DLV} || cleanexit 1 fi if [ 0$3 -ne $VERSION_MAJOR ]; then echo This script is version $VERSION, genesis info is for version $3.xx test -z ${DLV} || cleanexit 1 fi if [ x$1 != x$OS ]; then echo Operating system mismatch; this machine: $OS, but config is for $1 test -z ${DLV} || cleanexit 1 fi if [ x$2 != x$REL ]; then echo This machine runs $REL, but the configuration is for $2 test -z ${DLV} || cleanexit 2 fi log Ok log Fetching file list from $link for $nodename safefetch ${link}${nodename} ${dir}/${list} lognlr "Fetching:" for i in `cat ${dir}/${list}` do lognlr " ${i}" # $FETCH -o - ${link}${nodename}/${i} > ${dir}/${i}.new || cleanexit 1 safefetch ${link}${nodename}/${i} ${dir}/${i}.new done log . for i in `cat ${dir}/${list}` do case ${i} in linux.sh | config | txtconfig ) # log obsolete file: ${i} - skipped ;; resolv.conf | rc.node.local | rc.local) linkin /etc ${i} ;; snmpd.local.conf) linkin /usr/local/share/snmp ${i} ;; named.conf) linkin /etc/namedb ${i} ;; dhcpd.conf) linkin /usr/local/etc ${i} ;; zebra.conf | ospfd.conf) linkin /usr/local/etc/zebra ${i} ;; authorized_keys) linkin /root/.ssh ${i} ;; ssh_known_hosts) linkin /etc/ssh ${i} ;; daemons.sh) linkin /wl ${i} ;; *) echo Script cannot cope with ${i} - ignoring.. ;; esac done if [ -e /etc/rc.local ]; then # See if we are in rc.local if grep -q /config-node.sh /etc/rc.local; then echo As this node now has real configs - do enter a root password echo passwd \ || cleanexit 1 echo Removing /etc/rc.local rm -f /etc/rc.local echo Will drop write perms on the next reboot. fi fi # Record our name. echo ${nodename} > ${dir}/myname # Rebuild reverse lookups if test -e /etc/rc.node.local; then H=`cat /etc/rc.node.local | grep hostname | sed -e s/hostname=// | sed -e s/[\"\']//g` hostname $H else echo Warning: rc.node.local missing. fi if [ -r /etc/namedb/make-localhost -a ${CMD} != 'do_diff' ]; then ( cd /etc/namedb || exit 1 sh /etc/namedb/make-localhost || exit 1 ) || exit 1 fi cleanse || exit 1 if [ -e /etc/rc.empty.conf ] ; then rm /etc/rc.empty.conf || exit 1 echo removed /etc/rc.empty.conf - and rebooting in 30 seconds \(or press ctrl-C to abort\) read -t 30 DUMMY reboot fi test ${FORCE} = 'rw' && mount -u -r / exit 0