6 ## Copyright (c) 2005 David B. Harris <dbharris@eelf.ddts.net>
7 ## Copyright (c) 2005 Peter Palfrader <peter@palfrader.org>
9 ## This text is released under the "three-clause BSD license".
10 ## The full text of the license is available at the end of this file.
12 printf "\nrecvconf on %s processing:\n" "$(hostname -s)"
13 FILELIST=/etc/NOREPLY/recvconf.files
18 tempscript="$(mktemp)"
19 chmod 0600 "$tempscript"
21 tempdir="$(mktemp -d)"
23 # Read tarball from STDIN
29 copy_and_runcommands() {
31 local file perms user group precommand postcommand
32 file="$1"; perms="$2"; user="$3"; group="$4"; precommand="$5"; postcommand="$6"
34 if [ -f "$file" ]; then
35 if [ -h "$file" ]; then # File should NOT be a symlink
36 printf "\`%s' is a symlink, aborting.\n" "$file" >&2
40 if ! [ "$file" -nt "/$file" ]; then
45 if [ -n "$precommand" ]; then
46 printf "Running precommand \`%s' for %s\n" "$precommand" "$file" >&2
47 eval -- $precommand >&2
50 if [ -n "$perms" ]; then
51 chmod -- "$perms" "$file"
53 printf "Warning, no perms defined for \`%s', assuming 0640.\n" "$file" >&2
56 if [ -n "$user" ]; then
57 chown -- "$user" "$file"
59 printf "Warning, no user defined for \`%s', assuming root.\n" "$file" >&2
62 if [ -n "$group" ]; then
63 chgrp -- "$group" "$file"
65 printf "Warning, no group defined for \`%s', assuming root.\n" "$file" >&2
69 if [ ! -d "/$(dirname "$file")" ]; then
70 printf "Directory \`%s' does not exist, aborting.\n" "$(dirname "$file")" >&2
74 cp -a -- "$file" "/$(dirname "$file")" >&2
75 ls -l "/$(dirname "$file")/$(basename "$file")" >&2
77 if [ -n "$postcommand" ]; then
78 if ! grep -F -- "$postcommand" "$tempscript" > /dev/null 2>&1; then
79 printf "%s\n" "$postcommand" >> "$tempscript"
91 linenum="$(($linenum + 1))"
93 if printf "%s\n" "$line" | grep -E '^[[:space:]]*$' > /dev/null 2>&1; then
94 ## This line is an empty line; skip it
96 elif printf "%s" "$line" | grep -E '^[[:space:]]*#' > /dev/null 2>&1; then
97 ## This line is a comment; skip it
101 ## IN=0, so we're out of a stanza: better get a file declaration next
102 if [ "$IN" = "0" ] && ! printf "%s" "$line" | grep -E '^[[:space:]]*file[[:space:]]' > /dev/null 2>&1; then
103 printf "Error on line %s, file declaration expected. Got\n\t%s\n" "$linenum" "$line" >&2
105 elif [ "$IN" = 0 ] && printf "%s" "$line" | grep -E '^[[:space:]]*file[[:space:]]' > /dev/null 2>&1; then
106 ## Okay, we're just starting out; set $file and move on
107 file="$(printf "%s" "$line" | sed -e 's/[[:space:]]*file[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
110 elif [ "$IN" = 1 ] && printf "%s" "$line" | grep -E '^[[:space:]]*file[[:space:]]' > /dev/null 2>&1; then
111 ## Okay, not only are we at a file declaration, but this isn't our first one. Run the commands to process
112 ## the file, then set a $file to the new value and continue parsing.
113 [ -n "$file" ] && copy_and_runcommands "$file" "$perms" "$user" "$group" "$precommand" "$postcommand"
114 file="$(printf "%s" "$line" | sed -e 's/[[:space:]]*file[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
115 perms=""; user=""; group=""; precommand=""; postcommand=""
119 ## 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
120 if printf "%s" "$line" | grep -E '^[[:space:]]*perms[[:space:]]' > /dev/null 2>&1; then
121 perms="$(printf "%s" "$line" | sed -e 's/[[:space:]]*perms[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
123 elif printf "%s" "$line" | grep -E '^[[:space:]]*user[[:space:]]' > /dev/null 2>&1; then
124 user="$(printf "%s" "$line" | sed -e 's/[[:space:]]*user[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
126 elif printf "%s" "$line" | grep -E '^[[:space:]]*group[[:space:]]' > /dev/null 2>&1; then
127 group="$(printf "%s" "$line" | sed -e 's/[[:space:]]*group[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
129 elif printf "%s" "$line" | grep -E '^[[:space:]]*precommand[[:space:]]' > /dev/null 2>&1; then
130 precommand="$(printf "%s" "$line" | sed -e 's/[[:space:]]*precommand[[:space:]]\+\([^[:space:]#]*\)/\1/')"
132 elif printf "%s" "$line" | grep -E '^[[:space:]]*postcommand[[:space:]]' > /dev/null 2>&1; then
133 postcommand="$(printf "%s" "$line" | sed -e 's/[[:space:]]*postcommand[[:space:]]\+\([^[:space:]#]*\)/\1/')"
136 printf "Unknown token at line %s:\n\t%s\n" "$linenum" "$line"
141 ## This is the last stanza and the above loop has set the variables, but hasn't yet processed the file
142 [ -n "$file" ] && copy_and_runcommands "$file" "$perms" "$user" "$group" "$precommand" "$postcommand"
144 if [ -s "$tempscript" ]; then
145 tempoutput="$(mktemp)"
146 ## Post-copying commands to be run, run them here. Only display output if they exit with $? > 0
147 while read command; do
148 printf "Running postcommand \`%s' on %s.\n" "$command" "$(hostname -s)" >&2
149 if ! eval -- "(cd / && env -i $command)" > "$tempoutput" 2>&1; then
150 printf "Error, postcommand \`%s' on %s failed. Output follows:\n" "$command" "$(hostname -s)" >&2
151 cat -- "$tempoutput" >&2
157 # Check for any leftover files here; if there are any, exit with an error and print the list
158 if [ ! -z "$(find . -type f)" ]; then
159 printf "The following files were not listed in $FILELIST:\n%s\n" "$(find . -type f)" >&2
164 rm -f -- "$tempoutput"
165 rm -f -- "$tempscript"
169 printf "recvconf on %s finished.\n" "$(hostname -s)"
171 ## Redistribution and use in source and binary forms, with or without
172 ## modification, are permitted provided that the following conditions are
175 ## * Redistributions of source code must retain the above copyright
176 ## notice, this list of conditions and the following disclaimer.
178 ## * Redistributions in binary form must reproduce the above
179 ## copyright notice, this list of conditions and the following disclaimer
180 ## in the documentation and/or other materials provided with the
183 ## * Neither the names of the copyright owners nor the names of its
184 ## contributors may be used to endorse or promote products derived from
185 ## this software without specific prior written permission.
187 ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
188 ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189 ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
190 ## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
191 ## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
192 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
193 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
194 ## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
195 ## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
196 ## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
197 ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.