Explicitly set -e instead of getting it from the shebang
[mirror/dsa-puppet.git] / modules / geodns / files / common / recvconf
1 #!/bin/bash
2
3 set -e
4
5 ## Copyright (c) 2005 David B. Harris <dbharris@eelf.ddts.net>
6 ## Copyright (c) 2005 Peter Palfrader <peter@palfrader.org>
7
8 ## This text is released under the "three-clause BSD license".
9 ## The full text of the license is available at the end of this file.
10
11 printf "\nrecvconf on %s processing:\n" "$(hostname -s)"
12 FILELIST=/etc/NOREPLY/recvconf.files
13
14 temptar="$(mktemp)"
15 chmod 0600 "$temptar"
16
17 tempscript="$(mktemp)"
18 chmod 0600 "$tempscript"
19
20 tempdir="$(mktemp -d)"
21
22 # Read tarball from STDIN
23 gzip -dc > "$temptar"
24
25 cd "$tempdir"
26 tar xf "$temptar"
27
28 copy_and_runcommands() {
29
30     local file perms user group precommand postcommand
31     file="$1"; perms="$2"; user="$3"; group="$4"; precommand="$5"; postcommand="$6"
32
33     if [ -f "$file" ]; then
34         if [ -h "$file" ]; then # File should NOT be a symlink
35             printf "\`%s' is a symlink, aborting.\n" "$file" >&2
36             return 1
37         fi
38
39         if ! [ "$file" -nt "/$file" ]; then
40             rm -f "$file"
41             return 0
42         fi
43
44         if [ -n "$precommand" ]; then
45             printf "Running precommand \`%s' for %s\n" "$precommand" "$file" >&2
46             eval -- $precommand >&2
47         fi
48
49         if [ -n "$perms" ]; then
50             chmod -- "$perms" "$file"
51         else
52             printf "Warning, no perms defined for \`%s', assuming 0640.\n" "$file" >&2
53             chmod 0640 "$file"
54         fi
55         if [ -n "$user" ]; then
56             chown -- "$user" "$file"
57         else
58             printf "Warning, no user defined for \`%s', assuming root.\n" "$file" >&2
59             chown root "$file"
60         fi
61         if [ -n "$group" ]; then
62             chgrp -- "$group" "$file"
63         else
64             printf "Warning, no group defined for \`%s', assuming root.\n" "$file" >&2
65             chgrp root "$file"
66         fi
67
68         if [ ! -d "/$(dirname "$file")" ]; then
69             printf "Directory \`%s' does not exist, aborting.\n" "$(dirname "$file")" >&2
70             exit 1
71         fi
72
73         cp -a -- "$file" "/$(dirname "$file")" >&2
74         ls -l "/$(dirname "$file")/$(basename "$file")" >&2
75
76         if [ -n "$postcommand" ]; then
77             if ! grep -F -- "$postcommand" "$tempscript" > /dev/null 2>&1; then
78                 printf "%s\n" "$postcommand" >> "$tempscript"
79             fi
80         fi
81
82         rm -f -- "$file"
83     fi
84 }
85
86 IN=0
87 linenum=0
88 nextfile=""
89 while read line; do
90     linenum="$(($linenum + 1))"
91
92     if printf "%s\n" "$line" | grep -E '^[[:space:]]*$' > /dev/null 2>&1; then
93         ## This line is an empty line; skip it
94         continue
95     elif printf "%s" "$line" | grep -E '^[[:space:]]*#' > /dev/null 2>&1; then
96         ## This line is a comment; skip it
97         continue
98     fi
99
100     ## IN=0, so we're out of a stanza: better get a file declaration next
101     if [ "$IN" = "0" ] && ! printf "%s" "$line" | grep -E '^[[:space:]]*file[[:space:]]' > /dev/null 2>&1; then
102         printf "Error on line %s, file declaration expected. Got\n\t%s\n" "$linenum" "$line" >&2
103         exit 1
104     elif [ "$IN" = 0 ] && printf "%s" "$line" | grep -E '^[[:space:]]*file[[:space:]]' > /dev/null 2>&1; then
105         ## Okay, we're just starting out; set $file and move on
106         file="$(printf "%s" "$line" | sed -e 's/[[:space:]]*file[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
107         IN=1
108         continue
109     elif [ "$IN" = 1 ] && printf "%s" "$line" | grep -E '^[[:space:]]*file[[:space:]]' > /dev/null 2>&1; then
110         ## Okay, not only are we at a file declaration, but this isn't our first one. Run the commands to process
111         ## the file, then set a $file to the new value and continue parsing.
112         [ -n "$file" ] && copy_and_runcommands "$file" "$perms" "$user" "$group" "$precommand" "$postcommand"
113         file="$(printf "%s" "$line" | sed -e 's/[[:space:]]*file[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
114         perms=""; user=""; group=""; precommand=""; postcommand=""
115         continue
116     fi
117
118     ## 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
119     if printf "%s" "$line" | grep -E '^[[:space:]]*perms[[:space:]]' > /dev/null 2>&1; then
120         perms="$(printf "%s" "$line" | sed -e 's/[[:space:]]*perms[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
121         continue
122     elif printf "%s" "$line" | grep -E '^[[:space:]]*user[[:space:]]' > /dev/null 2>&1; then
123         user="$(printf "%s" "$line" | sed -e 's/[[:space:]]*user[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
124         continue
125     elif printf "%s" "$line" | grep -E '^[[:space:]]*group[[:space:]]' > /dev/null 2>&1; then
126         group="$(printf "%s" "$line" | sed -e 's/[[:space:]]*group[[:space:]]\+\([^[:space:]#]*\).*/\1/')"
127         continue
128     elif printf "%s" "$line" | grep -E '^[[:space:]]*precommand[[:space:]]' > /dev/null 2>&1; then
129         precommand="$(printf "%s" "$line" | sed -e 's/[[:space:]]*precommand[[:space:]]\+\([^[:space:]#]*\)/\1/')"
130         continue
131     elif printf "%s" "$line" | grep -E '^[[:space:]]*postcommand[[:space:]]' > /dev/null 2>&1; then
132         postcommand="$(printf "%s" "$line" | sed -e 's/[[:space:]]*postcommand[[:space:]]\+\([^[:space:]#]*\)/\1/')"
133         continue
134     else
135         printf "Unknown token at line %s:\n\t%s\n" "$linenum" "$line"
136     fi
137
138 done < "$FILELIST"
139
140 ## This is the last stanza and the above loop has set the variables, but hasn't yet processed the file
141 [ -n "$file" ] && copy_and_runcommands "$file" "$perms" "$user" "$group" "$precommand" "$postcommand"
142
143 if [ -s "$tempscript" ]; then
144     tempoutput="$(mktemp)"
145     ## Post-copying commands to be run, run them here. Only display output if they exit with $? > 0
146     while read command; do
147         printf "Running postcommand \`%s' on %s.\n" "$command" "$(hostname -s)" >&2
148         if ! eval -- "(cd / && env -i $command)" > "$tempoutput" 2>&1; then
149             printf "Error, postcommand \`%s' on %s failed. Output follows:\n" "$command" "$(hostname -s)" >&2
150             cat -- "$tempoutput" >&2
151             exit 1
152         fi
153     done < "$tempscript"
154 fi
155
156 # Check for any leftover files here; if there are any, exit with an error and print the list
157 if [ ! -z "$(find . -type f)" ]; then
158     printf "The following files were not listed in $FILELIST:\n%s\n" "$(find . -type f)" >&2
159     exit 1
160 fi
161
162 rm -f -- "$temptar"
163 rm -f -- "$tempoutput"
164 rm -f -- "$tempscript"
165 cd
166 rm -rf -- "$tempdir"
167
168 printf "recvconf on %s finished.\n" "$(hostname -s)"
169
170 ## Redistribution and use in source and binary forms, with or without
171 ## modification, are permitted provided that the following conditions are
172 ## met:
173 ## 
174 ##     * Redistributions of source code must retain the above copyright
175 ## notice, this list of conditions and the following disclaimer.
176 ## 
177 ##     * Redistributions in binary form must reproduce the above
178 ## copyright notice, this list of conditions and the following disclaimer
179 ## in the documentation and/or other materials provided with the
180 ## distribution.
181 ## 
182 ##     * Neither the names of the copyright owners nor the names of its
183 ## contributors may be used to endorse or promote products derived from
184 ## this software without specific prior written permission.
185 ## 
186 ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
187 ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188 ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
189 ## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
190 ## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
191 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
192 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
193 ## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
194 ## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
195 ## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
196 ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.