0
|
1 #! /bin/sh |
|
2 |
|
3 # generate periodic list of a DCC server's clients |
|
4 |
|
5 # This script should be run at midnight UTC, which is rarely midnight local |
|
6 # time. |
|
7 # It prefers to generates a new HTML file based on an existing file, but |
|
8 # will start from scratch if the output file does not already exist. |
|
9 |
|
10 # -A all, not just anonymous clients |
|
11 # -T do not tell dccd to clear its counters |
|
12 # -I do not wrap the result with <HTML></HTML> etc. so that |
|
13 # it can be server-side included into a web page |
|
14 # -Z timezone in case dccd is far away |
|
15 # -O cdcc-op something else to tell cdcc to do |
|
16 # -d ndays keep this many days of snapshots instead of 7 |
|
17 # -n clients number of clients in each snapshot |
|
18 # -s server host running dccd instead of localhost |
|
19 # -i server-ID DCC server-ID of the server |
|
20 # -o ofile output file |
|
21 |
|
22 # Rhyolite Software DCC 1.3.103-1.30 $Revision$ |
|
23 # @configure_input@ |
|
24 |
|
25 DCC_HOMEDIR=@prefix@ |
|
26 DEBUG= |
|
27 ARGS="xATIh:Z:O:d:n:s:p:i:o:" |
|
28 # check the args once to get the home directory to get server name and ID |
|
29 while getopts ":$ARGS" c; do |
|
30 case $c in |
|
31 x) set -x;; |
|
32 h) DCC_HOMEDIR="$OPTARG";; |
|
33 *) ;; |
|
34 esac |
|
35 done |
|
36 if test -s $DCC_HOMEDIR/dcc_conf; then |
|
37 . $DCC_HOMEDIR/dcc_conf |
|
38 fi |
|
39 |
|
40 CDCC=@bindir@/cdcc |
|
41 ALL=As |
|
42 CLEAR=clear |
|
43 INCLUDE=no |
|
44 OPS= |
|
45 NDAYS=7 |
|
46 NCLIENTS=100 |
|
47 TZ=UTC |
|
48 SERVER=localhost |
|
49 TITLE=`hostname` |
|
50 ID=$SRVR_ID |
|
51 PASSWD= |
|
52 OUT= |
|
53 USAGE="`basename $0`: [-xATI] [-Z timezone] [-O cdcc-op] [-d ndays] [-n nclients] |
|
54 [-s server] [-p password] -i server-ID -o ofile" |
|
55 OPTIND=1 |
|
56 while getopts "$ARGS" c; do |
|
57 case $c in |
|
58 x) set -x;; |
|
59 A) ALL=;; |
|
60 T) CLEAR=;; |
|
61 I) INCLUDE=yes;; |
|
62 h) ;; |
|
63 Z) TZ=$OPTARG;; |
|
64 O) OPS="$OPS$OPTARG; ";; |
|
65 d) NDAYS="$OPTARG";; |
|
66 n) NCLIENTS="$OPTARG";; |
|
67 s) SERVER="$OPTARG"; TITLE="$OPTARG";; |
|
68 p) PASSWD="; password $OPTARG";; |
|
69 i) ID="$OPTARG";; |
|
70 o) OUT="$OPTARG";; |
|
71 *) echo "$USAGE" 1>&2; exit 1;; |
|
72 esac |
|
73 done |
|
74 shift `expr $OPTIND - 1 || true` |
|
75 if test "$#" -ne 0; then |
|
76 echo "$USAGE" 1>&2 |
|
77 exit 1 |
|
78 fi |
|
79 |
|
80 # check that the ID is not 1 |
|
81 if expr "$ID" - 1 >/dev/null 2>&1; then : |
|
82 else |
|
83 echo "$USAGE" 1>&2 |
|
84 exit 1 |
|
85 fi |
|
86 |
|
87 # we need an output file |
|
88 if test "$OUT" = ""; then |
|
89 echo "use '-o ofile' to specify an output file" 1>&2 |
|
90 exit 1 |
|
91 fi |
|
92 |
|
93 CMD="${OPS}server $SERVER; id $ID$PASSWD" |
|
94 |
|
95 NCLIENTS5=`expr $NCLIENTS + 5` |
|
96 |
|
97 export TZ |
|
98 |
|
99 set -e |
|
100 |
|
101 |
|
102 # prefer the target directory for temporary files |
|
103 OUTDIR=`dirname $OUT` |
|
104 if test -z "$OUTDIR" -o -w "$OUTDIR"; then |
|
105 NEW=$OUT.new$$ |
|
106 TMP=$OUT.tmp$$ |
|
107 else |
|
108 NEW=/tmp/list-clients-new$$ |
|
109 TMP=/tmp/list-clients-tmp$$ |
|
110 fi |
|
111 trap "set +e; /bin/rm -f $NEW $TMP; exit" 0 1 2 15 |
|
112 |
|
113 |
|
114 # create or add to the HTML file |
|
115 makeout () { |
|
116 if test -s $OUT; then |
|
117 # start the new file with the head of the old file |
|
118 sed -e '/<!--clients sample-->/,$d' \ |
|
119 -e '/<\/BODY>/,$d' -e '/<\/body>,$/d' \ |
|
120 -e '/<\/HTML>/,$d' -e '/<\/html>/,$d' $OUT >$NEW |
|
121 else |
|
122 # create a new ouptut file |
|
123 if test "$INCLUDE" != yes; then |
|
124 cat >>$NEW <<EOF |
|
125 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> |
|
126 <HTML> |
|
127 <HEAD> |
|
128 <TITLE>$TITLE Clients</TITLE> |
|
129 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> |
|
130 </HEAD> |
|
131 |
|
132 <BODY> |
|
133 |
|
134 <H1>Recent $TITLE Clients</H1> |
|
135 <P> |
|
136 EOF |
|
137 fi |
|
138 fi |
|
139 |
|
140 if test -z "$HEADING"; then |
|
141 HEADING=`date` |
|
142 fi |
|
143 |
|
144 cat >>$NEW <<EOF |
|
145 <!--clients sample--> |
|
146 <H3>$HEADING</H3> |
|
147 <P> |
|
148 <PRE> |
|
149 EOF |
|
150 if test -s $TMP; then |
|
151 sed -e '1,/^ *server-ID/d' -e '/^$/d' -e '/^version/,$d' $TMP >>$NEW |
|
152 else |
|
153 echo "$*" >>$NEW |
|
154 fi |
|
155 |
|
156 cat >>$NEW <<EOF |
|
157 </PRE> |
|
158 |
|
159 EOF |
|
160 |
|
161 # save a limited number samples from the old file |
|
162 if test -s $OUT; then |
|
163 IGNORECASE=1 awk '/<!--clients sample-->/{ ++nsample; } |
|
164 /<!--end clients samples-->/{ nsample = 1; } |
|
165 /<\/body>/{ nsample = 1; } |
|
166 /<\/html>/{ nsample = 1; } |
|
167 { if (nsample < '$NDAYS' && nsample > 0) print $0; |
|
168 }' $OUT >>$NEW |
|
169 else |
|
170 echo '<!--end clients samples-->' >>$NEW |
|
171 fi |
|
172 |
|
173 if test "$INCLUDE" != yes; then |
|
174 if grep -i '</body>' $NEW >/dev/null; then : |
|
175 else |
|
176 echo '</BODY>' >>$NEW |
|
177 fi |
|
178 if grep -i '</html>' $NEW >/dev/null; then : |
|
179 else |
|
180 echo '</HTML>' >>$NEW |
|
181 fi |
|
182 fi |
|
183 |
|
184 cp -f $NEW $OUT |
|
185 |
|
186 if test ! -s $TMP; then |
|
187 echo "$*" 2>&1 |
|
188 exit 1 |
|
189 fi |
|
190 } |
|
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 # See if the server knows about client versions |
|
197 eval `$CDCC "$CMD; stats" 2>&1 \ |
|
198 | sed -n -e 's/^ *version [1-9]\.\([0-9]\{1,\}\)\.\([0-9]\{1,\}\) .*/VERS1=\1 VERS2=\2/p'\ |
|
199 -e 's/.*no working DCC server.*/VERS1=dead/p'` |
|
200 if test "$VERS1" = dead; then |
|
201 makeout "$SERVER is not responding" |
|
202 fi |
|
203 if test -z "$VERS1" -o -z "$VERS2"; then |
|
204 makeout "$SERVER of an unrecognized version" |
|
205 fi |
|
206 SVERS=`expr "${VERS1}000" + $VERS2` |
|
207 # dccd versions starting with *.3.32 answer `cdcc "clients -V"` |
|
208 # Starting with 3.67, dccd understands `cdcc "clients -A"` |
|
209 if test "$SVERS" -ge 3032; then |
|
210 if test "$SVERS" -ge 3067; then |
|
211 COPTS="-V$ALL" |
|
212 else |
|
213 COPTS="-Vs" |
|
214 fi |
|
215 else |
|
216 COPTS="-s" |
|
217 fi |
|
218 |
|
219 # Prime reverse DNS resolution with a dummy run and then do it for real |
|
220 $CDCC "$CMD; clients $COPTS $NCLIENTS5" >/dev/null |
|
221 $CDCC "$CMD; clients $COPTS $NCLIENTS5" >$TMP |
|
222 |
|
223 if test ! -s $TMP; then |
|
224 makeout "obtained no data from $SERVER" |
|
225 fi |
|
226 |
|
227 HEADING=`$CDCC "$CMD; stats $CLEAR" \ |
|
228 | sed -n \ |
|
229 -e '/clients since/h' \ |
|
230 -e 's@.* \([0-9]\{1,\}\) clients since.*@\1 Clients@p' \ |
|
231 -e 's@.* \([0-9]\{1,\}\) clients in.*@\1 Clients@p' \ |
|
232 -e '/reports added between/{' \ |
|
233 -e x -e G \ |
|
234 -e 's@.*clients since \(.*\)\n.*\( and .*\)@between \1\2@p' \ |
|
235 -e 's@.*ween \([^.]*\)\.[0-9]*\(.*\)@between \1\2@p' \ |
|
236 -e '}'` |
|
237 |
|
238 makeout "missing $TMP" |