summaryrefslogtreecommitdiff
path: root/recvconf
diff options
context:
space:
mode:
authorPeter Palfrader <peter@palfrader.org>2005-09-02 00:54:20 +0000
committerweasel <weasel@bc3d92e2-beff-0310-a7cd-cc87d7ac0ede>2005-09-02 00:54:20 +0000
commit63ac463b0355ae0f9bc86a879980c9fbd0ab4a00 (patch)
tree84761beea0e7588c482d378431485e8c0ceab692 /recvconf
parentfa6afc8ba4082a1818c27fb33f4eb379bcf3d2ee (diff)
Add recvconf
git-svn-id: svn+ssh://asteria.noreply.org/svn/weaselutils/trunk@5 bc3d92e2-beff-0310-a7cd-cc87d7ac0ede
Diffstat (limited to 'recvconf')
-rwxr-xr-xrecvconf192
1 files changed, 192 insertions, 0 deletions
diff --git a/recvconf b/recvconf
new file mode 100755
index 0000000..39f33e7
--- /dev/null
+++ b/recvconf
@@ -0,0 +1,192 @@
+#!/bin/bash -e
+
+## Copyright (c) 2005 David B. Harris <dbharris@eelf.ddts.net>
+## This text is released under the "three-clause BSD license".
+## The full text of the license is available at the end of this file.
+
+printf "\nrecvconf on %s processing:\n" "$(hostname -s)"
+FILELIST=/etc/oftc/recvconf.files
+
+temptar="$(mktemp)"
+chmod 0600 "$temptar"
+
+tempscript="$(mktemp)"
+chmod 0600 "$tempscript"
+
+tempdir="$(mktemp -d)"
+
+# Read tarball from STDIN
+gzip -dc > "$temptar"
+
+cd "$tempdir"
+tar xf "$temptar"
+
+copy_and_runcommands() {
+
+ local file perms user group precommand postcommand
+ file="$1"; perms="$2"; user="$3"; group="$4"; precommand="$5"; postcommand="$6"
+
+ if [ -f "$file" ]; then
+ if [ -h "$file" ]; then # File should NOT be a symlink
+ printf "\`%s' is a symlink, aborting.\n" "$file" >&2
+ return 1
+ fi
+
+ if ! [ "$file" -nt "/$file" ]; then
+ rm -f "$file"
+ return 0
+ fi
+
+ if [ -n "$precommand" ]; then
+ printf "Running precommand \`%s' for %s\n" "$precommand" "$file" >&2
+ eval -- $precommand >&2
+ fi
+
+ if [ -n "$perms" ]; then
+ chmod -- "$perms" "$file"
+ else
+ printf "Warning, no perms defined for \`%s', assuming 0640.\n" "$file" >&2
+ chmod 0640 "$file"
+ fi
+ if [ -n "$user" ]; then
+ chown -- "$user" "$file"
+ else
+ printf "Warning, no user defined for \`%s', assuming root.\n" "$file" >&2
+ chown root "$file"
+ fi
+ if [ -n "$group" ]; then
+ chgrp -- "$group" "$file"
+ else
+ printf "Warning, no group defined for \`%s', assuming root.\n" "$file" >&2
+ chgrp root "$file"
+ fi
+
+ if [ ! -d "/$(dirname "$file")" ]; then
+ printf "Directory \`%s' does not exist, aborting.\n" "$(dirname "$file")" >&2
+ exit 1
+ fi
+
+ cp -a -- "$file" "/$(dirname "$file")" >&2
+ ls -l "/$(dirname "$file")/$(basename "$file")" >&2
+
+ if [ -n "$postcommand" ]; then
+ if ! grep -F -- "$postcommand" "$tempscript" > /dev/null 2>&1; then
+ printf "%s\n" "$postcommand" >> "$tempscript"
+ fi
+ fi
+
+ rm -f -- "$file"
+ fi
+}
+
+IN=0
+linenum=0
+nextfile=""
+while read line; do
+ linenum="$(($linenum + 1))"
+
+ if printf "%s\n" "$line" | grep -E '^[[:space:]]*$' > /dev/null 2>&1; then
+ ## This line is an empty line; skip it
+ continue
+ elif printf "%s" "$line" | grep -E '^[[:space:]]*#' > /dev/null 2>&1; then
+ ## This line is a comment; skip it
+ continue
+ fi
+
+ ## IN=0, so we're out of a stanza: better get a file declaration next
+ if [ "$IN" = "0" ] && ! printf "%s" "$line" | grep -E '^[[:space:]]*file[[:space:]]' > /dev/null 2>&1; then
+ printf "Error on line %s, file declaration expected. Got\n\t%s\n" "$linenum" "$line" >&2
+ exit 1
+ elif [ "$IN" = 0 ] && printf "%s" "$line" | grep -E '^[[:space:]]*file[[:space:]]' > /dev/null 2>&1; then
+ ## Okay, we're just starting out; set $file and move on
+ file="$(printf "%s" "$line" | sed -e 's/[[:space:]]*file[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
+ IN=1
+ continue
+ elif [ "$IN" = 1 ] && printf "%s" "$line" | grep -E '^[[:space:]]*file[[:space:]]' > /dev/null 2>&1; then
+ ## Okay, not only are we at a file declaration, but this isn't our first one. Run the commands to process
+ ## the file, then set a $file to the new value and continue parsing.
+ [ -n "$file" ] && copy_and_runcommands "$file" "$perms" "$user" "$group" "$precommand" "$postcommand"
+ file="$(printf "%s" "$line" | sed -e 's/[[:space:]]*file[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
+ perms=""; user=""; group=""; precommand=""; postcommand=""
+ continue
+ fi
+
+ ## The last two if blocks weren't processed; thus this isn't a comment, a blank line, and we're in the middle of a stanza
+ if printf "%s" "$line" | grep -E '^[[:space:]]*perms[[:space:]]' > /dev/null 2>&1; then
+ perms="$(printf "%s" "$line" | sed -e 's/[[:space:]]*perms[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
+ continue
+ elif printf "%s" "$line" | grep -E '^[[:space:]]*user[[:space:]]' > /dev/null 2>&1; then
+ user="$(printf "%s" "$line" | sed -e 's/[[:space:]]*user[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
+ continue
+ elif printf "%s" "$line" | grep -E '^[[:space:]]*group[[:space:]]' > /dev/null 2>&1; then
+ group="$(printf "%s" "$line" | sed -e 's/[[:space:]]*group[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
+ continue
+ elif printf "%s" "$line" | grep -E '^[[:space:]]*precommand[[:space:]]' > /dev/null 2>&1; then
+ precommand="$(printf "%s" "$line" | sed -e 's/[[:space:]]*precommand[[:space:]]\+\([^[:space:]#]*\)/\1/')"
+ continue
+ elif printf "%s" "$line" | grep -E '^[[:space:]]*postcommand[[:space:]]' > /dev/null 2>&1; then
+ postcommand="$(printf "%s" "$line" | sed -e 's/[[:space:]]*postcommand[[:space:]]\+\([^[:space:]#]*\)/\1/')"
+ continue
+ else
+ printf "Unknown token at line %s:\n\t%s\n" "$linenum" "$line"
+ fi
+
+done < "$FILELIST"
+
+## This is the last stanza and the above loop has set the variables, but hasn't yet processed the file
+[ -n "$file" ] && copy_and_runcommands "$file" "$perms" "$user" "$group" "$precommand" "$postcommand"
+
+if [ -s "$tempscript" ]; then
+ tempoutput="$(mktemp)"
+ ## Post-copying commands to be run, run them here. Only display output if they exit with $? > 0
+ while read command; do
+ printf "Running postcommand \`%s' on %s.\n" "$command" "$(hostname -s)" >&2
+ if ! eval -- "$command" > "$tempoutput" 2>&1; then
+ printf "Error, postcommand \`%s' on %s failed. Output follows:\n" "$command" "$(hostname -s)" >&2
+ cat -- "$tempoutput" >&2
+ exit 1
+ fi
+ done < "$tempscript"
+fi
+
+# Check for any leftover files here; if there are any, exit with an error and print the list
+if [ ! -z "$(find . -type f)" ]; then
+ printf "The following files were not listed in /etc/oftc/recvconf.files:\n%s\n" "$(find . -type f)" >&2
+ exit 1
+fi
+
+rm -f -- "$temptar"
+rm -f -- "$tempoutput"
+rm -f -- "$tempscript"
+cd
+rm -rf -- "$tempdir"
+
+printf "recvconf on %s finished.\n" "$(hostname -s)"
+
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+##
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+##
+## * Redistributions in binary form must reproduce the above
+## copyright notice, this list of conditions and the following disclaimer
+## in the documentation and/or other materials provided with the
+## distribution.
+##
+## * Neither the names of the copyright owners nor the names of its
+## contributors may be used to endorse or promote products derived from
+## this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.