Mercurial > notdcc
diff misc/updatedcc.in @ 0:c7f6b056b673
First import of vendor version
author | Peter Gervai <grin@grin.hu> |
---|---|
date | Tue, 10 Mar 2009 13:49:58 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/updatedcc.in Tue Mar 10 13:49:58 2009 +0100 @@ -0,0 +1,597 @@ +#! /bin/sh + +# Fetch, build, install, and start a new version of the DCC just +# as it was configured last time. + +# This script should only be used after the DCC has been correctly configured. + +# If this script fails in its efforts to use wget, curl, fetch, or ftp +# to download a new tarball, then manually download a tarball to +# build subdirectory in the DCC home directory, probably @prefix@/build. +# This script unpacks the newest DCC tarball it finds in that directory, +# which will probably be the manually download file. + + +# This script should usually not be used if large configuration changes are +# needed. Instead use `./configure ...; make install` as usual. That will +# create a new version of this script with the ./configure settings captured. +# However, -eENV=VAL and -cCONF=VAL can be used to tweak an installation, +# as in `updatedcc -c--with-uid=dcc` `updatedcc -c--without-uid` +# or `updatedcc -e DBGFLAGS=-g` + +# -e ENV=VAL set environment variable ENV to VAL before running ./configure + +# -c CONF=VAL add "CONF=VAL" to the end of the settings given ./configure + +# -s base-URL fetch the tarball using base-URL instead of the default. +# The name of the tarball is appended to base-URL. + +# -V x.y.z try to fetch version x.y.z of the tarball instead of the +# the most recent verison + +# -C pfile fetch theDCC source using parameters in pfile + +# -T tgt target instead of "install" for `make` + +# -U only fetch, unpack, and configure the tarball. Do not compile +# or install the software. + +# -K cron (kron) mode; configure, compile, and install only +# if the fetched version differs, and be silent when +# nothing is done + +# -x debug +# -v verbose + + +# This script should be run as root, but can be run as the non-root +# user that runs dccm and dccd. If not run as root, it cannot install +# man pages or user commands including cdcc and dccproc. + +# The following environment variables are set by this script to their values +# when ./configure or this script was last run: +# Unsetting variables that are not set often yields a non-zero command status +# so do this before watching for error from mkdir and so forth +export @UPDATEDCC_ENV@ +unset @UPDATEDCC_ENV@ +ENV_SET="@UPDATEDCC_ENV_SET@" +@UPDATEDCC_ENV_SET@ +@UPDATEDCC_ENV_EXPORT@ + + +# Copyright (c) 2008 by Rhyolite Software, LLC +# +# This agreement is not applicable to any entity which sells anti-spam +# solutions to others or provides an anti-spam solution as part of a +# security solution sold to other entities, or to a private network +# which employs the DCC or uses data provided by operation of the DCC +# but does not provide corresponding data to other users. +# +# Permission to use, copy, modify, and distribute this software without +# changes for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear in all +# copies and any distributed versions or copies are either unchanged +# or not called anything similar to "DCC" or "Distributed Checksum +# Clearinghouse". +# +# Parties not eligible to receive a license under this agreement can +# obtain a commercial license to use DCC by contacting Rhyolite Software +# at sales@rhyolite.com. +# +# A commercial license would be for Distributed Checksum and Reputation +# Clearinghouse software. That software includes additional features. This +# free license for Distributed ChecksumClearinghouse Software does not in any +# way grant permision to use Distributed Checksum and Reputation Clearinghouse +# software +# +# THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC +# BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +# SOFTWARE. +# Rhyolite Software DCC 1.3.103-1.111 $Revision$ +# @configure_input@ + +# English messages so grep can suppress them; +# simple collating sequence for sort +# sane gcc error messages +LC_ALL=C; export LC_ALL + + +RELEASE=1.3.103 +HTTP_REFERER=DCC-$RELEASE-script; export HTTP_REFERER + +DCC_HOMEDIR=@prefix@ +DCC_LIBEXEC=@libexecdir@ # in case dcc_conf has disappeared +. $DCC_HOMEDIR/dcc_conf +BDIR=$DCC_HOMEDIR/build +DCCDIR=$BDIR/dcc +OK_MARK=$BDIR/.updatedcc_ok +BURLS= +VERSION= + +ME=`basename $0` +USAGE="$ME: [-xvUK] [-e ENV=VAL] [-c CONF=VAL] [-s base-URL] [-V x.y.z]\\ + [-C pfile] [-T make-tgt]" +VERBOSE= +DEBUG= +UNPACK= +CRON= +CONFS= +PFILE="@UPDATEDCC_PFILE@" +MAKE_TGT=install +while getopts "xvUKe:c:s:V:p:C:T:" c; do + case $c in + x) set -x; DEBUG=-x VERBOSE=yes;; + v) VERBOSE=yes;; + U) UNPACK=yes;; + K) CRON=yes;; + e) # quote any odd characters + SETTING=`echo "$OPTARG" | sed -e 's/\([^-_/:=+,.a-zA-Z0-9]\)/\\\\\1/g'` + eval "$SETTING" + export `expr "$OPTARG" : '\([^=]*\).*' || true` + ENV_SET="$ENV_SET $SETTING" + ;; + c) CONFS="$CONFS $OPTARG";; + s) BURLS="$BURLS $OPTARG";; + V) VERSION=`expr "X$OPTARG" : 'X\([1-9]\.[1-9][0-9]*\.[1-9][0-9]*\)'` + if test "$VERSION" != "$OPTARG"; then + echo "invalid -V $OPTARG" 1>&2; exit 1; + fi + ;; + C) PFILE="$OPTARG";; + T) MAKE_TGT="$OPTARG";; + p) echo "All 3 DCC tarballs are now the same";; + *) echo "$USAGE" 1>&2; exit 1;; + esac +done +shift `expr $OPTIND - 1 || true` +if test "$#" -ne 0; then + echo "$USAGE" 1>&2; exit 1 +fi + +if test -z "$VERBOSE"; then + WGETQUIET='-nv' + CURLQUIET= + CONFQUIET='--quiet' + MQUIET= +else + WGETQUIET= + CURLQUIET= + CONFQUIET= + MQUIET='#' +fi + +# assume cron mode if stdin is not a tty +if test -z "$CRON" && test -n "`tty 2>&1 | grep 'not a tty'`"; then + echo "assume -K because stdin is not a tty" + CRON=assumed +fi +exec </dev/null +if test -n "$CRON"; then + # be quite in cron mode unless told otherwise + if test -z "$VERBOSE" -a "$CRON" != assumed; then + WGETQUIET='-q' + CURLQUIET='-s' + exec >/dev/null + fi + exec 3>&1 # preserve stdout in case cron mode does work + + if test -n "$UNPACK"; then + echo "-u (unpack only) and -K (cron mode) are incompatible" 1>&2 + exit 1 + fi + if test -n "$VERSION"; then + echo "-V$VERSION and -K (cron mode) are incompatible" 1>&2 + exit 1 + fi + # Do nothing if we have run recently. + # Pick a somewhat random number of days to reduce the crowds that + # otherwise happen on anniversaries of releases. + DAYS=`ps | cksum | sed -e 's/ /9/g' -e 's/[^0-9]*\([0-9]\{1,6\}\).*/\1/'` + DAYS=`expr '(' $DAYS % 3 ')' + 6` + if test -d $DCCDIR \ + && test -n "`find $OK_MARK -mtime -$DAYS 2>/dev/null`"; then + echo "less than $DAYS days since the last updatedcc -K; stop" + exit 0 + fi +fi + + +# see if we have permission +set -e +if test ! -d $BDIR; then + rm -f $BDIR || true + mkdir $BDIR +fi +cd $BDIR +if test ! -d $DCCDIR; then + rm -f $DCCDIR || true + mkdir $DCCDIR +fi +set +e +for NM in "$DCC_HOMEDIR" "$DCC_LIBEXEC"; do + if test -n "$NM" -a ! -w "$NM"; then + echo "cannot write $NM; must $ME be run as root?" 1>&2 + exit 1 + fi +done +find $DCCDIR -type d | while read SUBDIR; do + if test ! -w $SUBDIR; then + echo "cannot write $SUBDIR; must $ME be run as root?" 1>&2 + # but maybe this is ok + break + fi + done + +if test -z "$PFILE"; then + if test -n "@UPDATEDCC_PFILE@"; then + CONFS="--without-updatedcc-pfile $CONFS" + fi + # quietly use $DCC_HOMEDIR/.updatedcc_pfile if it exists + if test -s "$DCC_HOMEDIR/.updatedcc_pfile"; then + PFILE="$DCC_HOMEDIR/.updatedcc_pfile" + fi +else + PFILE=`echo $PFILE | sed "s@^[^/]@$DCC_HOMEDIR/&@"` + # add it to the configuration if it is not the default + if test "$PFILE" != "$DCC_HOMEDIR/.updatedcc_pfile"; then + CONFS="--with-updatedcc-pfile=$PFILE $CONFS" + fi +fi +if test -f "$PFILE" -a ! -r "$PFILE"; then + echo "cannot read $PFILE; must $ME be run as root?" 1>&2 +fi +if test -n "$PFILE"; then + . $PFILE +fi + +if test -z "$BURLS"; then + # $SERVER is set from $DCC_HOMEDIR/.updatedcc_pfile + if test -n "$SERVER"; then + BURLS="$SERVER" + else + BURLS="http://www.dcc-servers.net/dcc/source http://www.rhyolite.com/dcc/source ftp://ftp.dcc-servers.net/src/dcc ftp://ftp.rhyolite.com/src/dcc" + fi +fi + +if test -z "$VERSION"; then + DLTBALL="dcc.tar.Z" + TBALL= + TBALL_PATH="$DLTBALL" +else + DLTBALL="dcc-$VERSION.tar.Z" + TBALL="$DLTBALL" + TBALL_PATH="old/$DLTBALL" +fi +# don't blab the password needlessly +print_url () { + PURL=`echo "$2" | sed -e 's%^\([fhtp]*://\)[^/@:]\{1,\}:[^/@:]\{1,\}@%\1%'` + echo "using $1 to get $PURL" +} + + +TRAPS="0 1 2 15" +stop_dccd () { + if test "$DCC_UPDATEDCC_FAST" = yes; then + return + fi + DCC_UPDATEDCC_FAST= export DCC_UPDATEDCC_FAST + + # trapped signals on some systems must start by turning themselves off, + # especially #0 + trap "trap $TRAPS; echo 'stopping update; please wait'; $DCC_RESTART" $TRAPS + + # start stopping dccd now in the hope that it will have released the + # sockets and database files by the time we need to restart it. + $DCC_LIBEXEC/stop-dccd $DEBUG + # switch to a working server + @bindir@/cdcc -q rtt >/dev/null 2>&1 || true +} + +if test -n "$UNPACK"; then + DCC_RESTART= +else + DCC_RESTART="$DCC_LIBEXEC/rcDCC $DEBUG start" + if test -z "$CRON"; then + # let compiling be slow instead of stopping the server in cron mode + stop_dccd + fi +fi + + +# use fetch, wget, curl, or ftp that understands URLs +# notice '-c --with-fetch_cmd=X' +PGM=`echo "X $confs" | sed -n -e 's/.*--with-fetch[-_]cmd=\([^ ]*\)/\1/p'` +if test -z "$PGM"; then + PGM=@FETCH_CMD@ +fi +PGM_B=`basename $PGM` +SUCCESS= +oldTZ=$TZ; TZ=UTC; export TZ # Solaris FTP is confused by dates +if test "$PGM_B" = wget; then + for BURL in $BURLS; do + URL="$BURL/$TBALL_PATH" + print_url "$PGM_B" "$URL" + # Do not use --mirror because -r results in a 0 exit status + # even on failure. + # Do not use --no-remove-listing, -nr, or --dont-remove-listing + # because none of them are supported by all versions of wget. + # At least some versions of wget exit with 0 after having done + # nothing but emitting a usage message. + if $PGM $WGETQUIET -nd --no-host-directories -N \ + --retr-symlinks --passive-ftp @FETCH_WGET_OPTS@ "$URL"; then + if test -s $DLTBALL; then + # notice if we get an HTTP error document with or without + # HTTP headers + if test -z "`sed -n -e 2q \ + -e 's/.*DOCTYPE.*/HTML/p' \ + -e 's/<HEAD>/HTML/p' -e 's/<head>/HTML/p' \ + $DLTBALL`"; then + SUCCESS="yes" + break + fi + # do not leave a broken file + rm -f $DLTBALL + fi + fi + echo + done + PGM_B= +fi + +if test "$PGM_B" = fetch; then + for BURL in $BURLS; do + URL="$BURL/$TBALL_PATH" + print_url "$PGM_B" "$URL" + if $PGM -p -q -m "$URL"; then + if test -s $DLTBALL; then + SUCCESS="yes" + break + fi + fi + echo + done + PGM_B= +fi + +if test "$PGM_B" = curl; then + for BURL in $BURLS; do + URL="$BURL/$TBALL_PATH" + print_url "$PGM_B" "$URL" + if $PGM @FETCH_CURL_OPTS@ -R --connect-timeout 30 --max-time 600 \ + $CURLQUIET "$URL" -o $DLTBALL; then + # --fail does not work on at least some versions of curl + if test -s $DLTBALL; then + # notice if we get an HTTP error document with or without + # HTTP headers + if test -z "`sed -n -e 2q \ + -e 's/.*DOCTYPE.*/HTML/p' \ + -e 's/<HEAD>/HTML/p' -e 's/<head>/HTML/p' \ + $DLTBALL`"; then + SUCCESS="yes" + break + fi + # do not leave a broken file + rm -f $DLTBALL + fi + fi + echo + done + PGM_B= +fi + +# try FTP if it is the right choice or the right choice has not worked +if test "$PGM_B" = ftp -o ! -s $DLTBALL; then + if test "$PGM_B" != ftp ; then + PGM_B=ftp + PGM=ftp + fi + for BURL in $BURLS; do + URL="$BURL/$TBALL_PATH" + print_url "$PGM_B" "$URL" + if $PGM -p "$URL"; then + if test -s $DLTBALL; then + SUCCESS="yes" + break + fi + fi + echo + done + # if that did not work, try ancient anonymous FTP + if test ! -s $DLTBALL; then + for URL in $BURLS; do + HOST=`expr "$URL" : "ftp://\([^/]*\)/"` + SRC=`expr "$URL" : "ftp://[^/]*/\(.*\)"` + if test -z "$HOST" -o -z "$SRC"; then + continue + fi + USR=`expr "$HOST" : "\([^/:]*\):"` + if test -z "$USR"; then + USR=anonymous + PASSWD=`hostname` + else + PASSWD=`expr "$HOST" : "$USR:\(.*\)@.*"` + HOST=`expr "$HOST" : ".*@\(.*\)"` + fi + echo "try old anonymous FTP with $HOST and $SRC" + (echo "user $USR $PASSWD "; \ + echo "binary"; \ + echo "get $SRC/$DLTBALL $DLTBALL") \ + | ftp -n $HOST + if test -s $DLTBALL; then + SUCCESS="yes" + break + fi + # some versions of ftp like to leave empty files + rm -f $DLTBALL + done + fi + PGM_B= +fi + +if test -n "$PGM_B"; then + echo "unrecognized fetch program $PGM_B" 1>&2; exit 1 +fi +if test -z "$oldTZ"; then + unset TZ +else + TZ=$oldTZ +fi +if test -z "$SUCCESS" -o ! -s $DLTBALL; then + echo + echo "failed to fetch a new copy of $DLTBALL" 1>&2 + if test -n "$PFILE"; then + echo "is $PFILE correct?" 1>&2 + fi + # try to install an existing tar ball if not in cron mode + if test -n "$CRON"; then + exit 1 + fi + echo +fi +set -e + +# pick the newest tarball, possibly one fetched manually and already present +# instead of the official tarball fetched by this script. +if test -z "$TBALL"; then + TBALL=`ls -Lt dcc*.tar.Z | head -1` +fi +if test ! -s "$TBALL"; then + echo "failed to fetch tarball; nothing to install" 1>&2 + exit 1 +fi + +NEW_DCC=`zcat "$TBALL" | tar -tf - \ + | sed -n -e '2q' -e 's@\(dcc-[0-9.]*\)/.*@\1@p'` +if test -z "$NEW_DCC"; then + echo "failed to find version in $TBALL" 1>&2 + exit 1 +fi + +# finished if we should only install new versions +if test -n "$CRON"; then + exec 1>&3 # restore stdout + if test "$NEW_DCC" = "dcc-$RELEASE" \ + && test -z "`find $TBALL -follow -newer $DCCDIR`"; then + echo "new $TBALL is the same version $RELEASE; stop" + touch $OK_MARK + exit 0 + fi + stop_dccd +fi + +# Move the unpacked tarball into the build directory named dcc +# while preserving any foreign files. +# Empty the target build directory of old DCC source and generated files. +MNM=.manifest +if test -d dcc; then + if test ! -f dcc/$MNM; then + if test `find dcc -type f -print | wc -l` -gt 50; then + # deal with old versions without .manifest files + echo delete $DCCDIR + rm -rf dcc + fi + else + cd dcc + set +e + @DCCMAKE@ purge >/dev/null 2>&1 + cd $BDIR + rmdir dcc 2>/dev/null + set -e + if test -d dcc; then + find dcc -type f -print \ + | sed -e '1s/./preserving &/' -e '2,$s/./ &/' + cd $BDIR + fi + fi +fi + +echo "unpack $TBALL into $DCCDIR" +rm -rf $NEW_DCC +zcat $TBALL | tar -xf - 2>&1 | head + +if test -n "$UNPACK"; then + echo "will configure but *NOT* build or install $NEW_DCC" +else + echo "will configure, build, and install $NEW_DCC" +fi +if test ! -d dcc; then + rm -rf dcc + mv $NEW_DCC dcc +else + # install top directories for preserved files first + find $NEW_DCC -name $MNM -print | sort | while read NM; do + DIR=`expr $NM : "$NEW_DCC/\(.*\)/$MNM" || true` + if test -z "$DIR"; then + DIR=. + fi + if test ! -d $NEW_DCC/$DIR; then + # we already moved this directory + continue + fi + # if we can, move the entire directory from the directory in the + # unpacked tarball to the corresponding build directory + if test ! -d $DCCDIR/$DIR; then + # first remove a possible stray file with the target name + rm -f $DCCDIR/$DIR || true + mv $NEW_DCC/$DIR $DCCDIR/$DIR + continue + fi + # otherwise move individual files from the unpacked tarball directory + cd $NEW_DCC/$DIR + mv `cat $MNM` $DCCDIR/$DIR + cd $BDIR + done + rm -rf $NEW_DCC +fi + +cd $DCCDIR + +# turn off FreeBSD blather about object directories +if test -z "$MAKEOBJDIRPREFIX"; then + MAKEOBJDIRPREFIX=; export MAKEOBJDIRPREFIX +fi + +if test -n "$ENV_SET"; then + echo "+ $ENV_SET" +fi +echo "+ ./configure @UPDATEDCC_PARMS@ $CONFQUIET $CONFS" +./configure @UPDATEDCC_PARMS@ $CONFQUIET $CONFS + +if test -n "$UNPACK"; then + exit +fi +trap "trap $TRAPS; echo 'stopping; please wait'; \ + $DCC_RESTART; @DCCMAKE@ purge >/dev/null 2>&1" $TRAPS + +@DCCMAKE@ $MAKE_TGT \ + | sed -e "$MQUIET/^[a-z0-9_]*.c: In function .*/d" \ + -e "$MQUIET/ warning: .%.. yields only last 2 digits of year/d" \ + -e "$MQUIET/^make.*is up to date/d" \ + -e "$MQUIET/^make.*Nothing to be done for/d" \ + -e "$MQUIET/^[a-z\/]*cc/s/-W[-a-z]*//g" \ + -e "$MQUIET/^[a-z\/]*cc/s@-m[0-9a-z=]*@@g" \ + -e "$MQUIET/^[a-z\/]*cc/s@-D_FILE_OFFSET_BITS=64@@g" \ + -e "$MQUIET/^[a-z\/]*cc/s@-D_LARGEFILE_SOURCE@@g" \ + -e "$MQUIET/^[a-z\/]*cc/s@-D_REENTRANT@@g" \ + -e "$MQUIET/^[a-z\/]*cc/s@-I[-a-zA-Z0-9/.]*@@g" \ + -e "$MQUIET/^[a-z\/]*cc/s@-I[-a-zA-Z0-9/.]*@@g" \ + -e "$MQUIET/^[a-z\/]*cc/s@-fno-strict-aliasing@@g" \ + -e "$MQUIET/^[a-z\/]*cc/s@-pipe@@g" \ + -e "$MQUIET/^building static .* library/d" \ + -e "$MQUIET/^ranlib/d" \ + -e "$MQUIET/^rm -f \.depend/d" \ + -e "$MQUIET/^mkdep/d" \ + -e "$MQUIET/^echo .* >> \.depend/d" \ + -e "$MQUIET/^g*cc/s@[ ]\{1,\}@ @g" + +touch $OK_MARK + +# finally start the new version and switch back to the local server +trap $TRAPS +$DCC_RESTART +@bindir@/cdcc -q rtt >/dev/null 2>&1