chiark / gitweb /
close idle connections and spot unresponsive ones
[innduct.git] / backends / actsyncd.in
1 #! /bin/sh
2 # fixscript will replace this line with code to load innshellvars
3
4 # @(#) $Id: actsyncd.in 6490 2003-10-18 05:49:04Z rra $
5 # @(#) Under RCS control in /usr/local/news/src/inn/local/RCS/actsyncd.sh,v
6 #
7 # actsyncd - actsync daemon
8 #
9 # usage:
10 #       actsyncd [-x] config_file [debug_level [debug_outfmt]]
11 #
12 #       -x              xexec instead of reload
13 #       config_file     name of file used to determine how to run actsync
14 #       debug_level     force no action and use -v debug_level
15 #       debug_outfmt    change -o a1 output to -o debug_outfmt for debug
16
17 # By: Landon Curt Noll          chongo@toad.com         (chongo was here /\../\)
18 #
19 # Copyright (c) Landon Curt Noll, 1993.
20 # All rights reserved.
21 #
22 # Permission to use and modify is hereby granted so long as this 
23 # notice remains.  Use at your own risk.  No warranty is implied.
24
25 # preset vars
26 #
27
28 # Our lock file
29 LOCK="${LOCKS}/LOCK.actsyncd"
30 # where actsync is located
31 ACTSYNC="${PATHBIN}/actsync"
32 # exit value of actsync if unable to get an active file
33 NOSYNC=127
34
35 # parse args
36 #
37 if [ $# -gt 1 ]; then
38     case $1 in
39     -x|-r) shift ;;     # no longer relevant
40     esac
41 fi
42 case $# in
43     1) cfg="$1"; DEBUG=; DEBUG_FMT=; ;;
44     2) cfg="$1"; DEBUG="$2"; DEBUG_FMT=; ;;
45     3) cfg="$1"; DEBUG="$2"; DEBUG_FMT="$3"; ;;
46     *) echo "usage: $0 [-x] config_file [debug_level [debug_outfmt]]" 1>&2;
47        exit 1 ;;
48 esac
49 if [ ! -s "$cfg" ]; then
50     echo "$0: config_file not found or empty: $ign" 1>&2
51     exit 2
52 fi
53
54 # parse config_file
55 #
56 host="`sed -n -e 's/^host=[     ]*//p' $cfg | tail -1`"
57 if [ -z "$host" ]; then
58     echo "$0: no host specified in $cfg" 1>&2
59     exit 3
60 fi
61 flags="`sed -n -e 's/^flags=[   ]*//p' $cfg | tail -1`"
62 if [ -z "$flags" ]; then
63     echo "$0: no flags specified in $cfg" 1>&2
64     exit 4
65 fi
66 ign="`sed -n -e 's/^ignore_file=[       ]*//p' $cfg | tail -1`"
67 if [ -z "$ign" ]; then
68     echo "$0: no ignore file specified in $cfg" 1>&2
69     exit 5
70 fi
71 ftp="`sed   -n -e 's/^ftppath=[         ]*//p' $cfg | tail -1`"
72 spool="`sed -n -e 's/^spool=[   ]*//p' $cfg | tail -1`"
73 if [ -z "$spool" ]; then
74     spool=$SPOOL
75     #echo "$0: no spool directory specified in $cfg" 1>&2
76     #exit 6
77 fi
78 if [ ! -f "$ign" ]; then
79     ign="${PATHETC}/$ign"
80 fi
81 if [ ! -s "$ign" ]; then
82     echo "$0: ignore_file not found or empty: $ign" 1>&2
83     exit 7
84 fi
85
86 # force -o c mode (overrides any -o argument in the command line)
87 #
88 if [ -z "$DEBUG" ]; then
89
90     # standard actsyncd output mode
91     flags="$flags -o c"
92
93 # DEBUG processing, if debug_level was given
94 #
95 else
96
97     if [ ! -z "$ftp" ]; then
98         echo "$0: cannot use DEBUG mode with ftp (yet)" >&2
99         exit 88;
100     fi
101
102     # force -v level as needed
103     flags="$flags -v $DEBUG"
104
105     # force -o level but reject -o x modes
106     if [ ! -z "$DEBUG_FMT" ]; then
107         case "$DEBUG_FMT" in
108         x*) echo "$0: do not use any of the -o x debug_outfmt modes!" 1>&2;
109             exit 8 ;;
110         *) flags="$flags -o $DEBUG_FMT" ;;
111         esac
112     fi
113
114     # execute actsync directly
115     echo "DEBUG: will execute $ACTSYNC -i $ign $flags $host" 1>&2
116     eval "$ACTSYNC -i $ign $flags $host"
117     status="$?"
118     echo "DEBUG: exit status $status" 1>&2
119     exit "$status"
120 fi
121
122 # Lock out others
123 #
124 shlock -p $$ -f "${LOCK}" || {
125     echo "$0: Locked by `cat '${LOCK}'`" 1>&2
126     exit 9
127 }
128
129 # setup
130 #
131 origdir=`pwd`
132 workdir="${TMPDIR}/actsyncd"
133 ctlinndcmds="cc_commands"
134 out="sync.msg"
135 cleanup="$SED -e 's/^/    /' < $out; cd ${origdir}; rm -rf '$workdir' '$LOCK'"
136 trap "eval $cleanup; exit 123" 1 2 3 15
137
138 set -e
139 rm -rf "$workdir"
140 mkdir "$workdir"
141 cd "$workdir"
142 set +e
143
144 rm -f "$out"
145 touch "$out"
146 chmod 0644 "$out"
147
148 # try to sync 
149
150 # Try to sync off of the host.  If unable to connect/sync then retry
151 # up to 9 more times waiting 6 minutes between each try.
152 #
153 echo "=-= `date` for $host" >>$out 2>&1
154 for loop in 1 2 3 4 5 6 7 8 9 10; do
155
156     # get the active file to compare against
157     status=0
158     case $host in
159     /*) cp $host          active; status=$? ;;
160     .*) cp $origdir/$host active; status=$? ;;
161      *)
162         if [ -z "$ftp" ]; then
163            port=`expr "$host" : '.*:\(.*\)'`
164            if [ -n "$port" ]; then
165              port="-p $port"
166              host=`expr "$host" : '\(.*\):.*'`
167            fi
168            echo "getlist -h $host $port" >>$out
169            if getlist -h $host $port > active 2>>$out; then
170              :
171            else
172              status=$NOSYNC
173            fi
174         else
175            echo "$GETFTP ftp://$host/$ftp" >>$out
176            $GETFTP ftp://$host/$ftp >>$out 2>&1
177            status=$?
178            if [ "$status" -ne 0 ]; then
179              status=$NOSYNC
180            else
181              case "$ftp" in
182              *.gz)
183                    echo "$GZIP -d active" >>$out
184                    if $GZIP -d active >>$out 2>&1; then
185                      :
186                    else
187                      status=1
188                    fi
189                    ;;
190              *.Z)
191                    echo "$UNCOMPRESS active" >>$out
192                    if $UNCOMPRESS active >>$out 2>&1; then
193                      :
194                    else
195                      status=1
196                    fi
197                    ;;
198              esac
199            fi
200         fi
201         ;;
202     esac
203
204     if [ "$status" -ne "$NOSYNC" ]; then
205
206         # detect bad status
207         #
208         if [ "$status" -ne 0 ]; then
209             echo "FATAL: `date` for $host exit $status" >>$out
210             eval $cleanup
211             exit "$status"
212         fi
213
214         echo "$ACTSYNC -i $ign $flags ./active" >>$out
215         eval "$ACTSYNC -i $ign $flags ./active >$ctlinndcmds 2>>$out"
216
217         if [ $? -ne 0 ]; then
218             echo "FATAL: `date` for $host actsync balked" >>$out
219             eval $cleanup
220             exit $?
221         fi
222
223         if [ ! -s $ctlinndcmds ]; then
224             echo "No changes need to be made" >>$out
225         else
226             echo "=-= `date` for $host, updating active" >>$out
227             echo "mod-active $ctlinndcmds" >>$out
228             mod-active $ctlinndcmds >>$out 2>&1
229
230             if [ $? -ne 0 ]; then
231                 echo "FATAL: `date` for $host mod-active FAILED" >>$out
232                 eval $cleanup
233                 exit 1
234             fi
235         fi
236
237         # normal exit - all done
238         #
239         echo "=-= `date` for $host, end" >>$out
240         eval $cleanup
241         exit 0
242     fi
243
244     # failed to get the remote active file
245     echo "=-= `date` for $host failed to connect/sync, retrying" >>$out
246
247     # wait 6 minutes
248     #
249     sleep 360
250 done
251
252 # give up
253 #
254 echo "FATAL: `date` for $host failed to connect/sync 10 times" >>$out 2>&1
255 eval $cleanup
256 exit 1