#! /bin/bash # $Id: recvstats.sh.in,v 1.1.1.1 2005/11/11 21:32:03 faxguy Exp $ # # HylaFAX Facsimile Software # # Copyright (c) 1990-1996 Sam Leffler # Copyright (c) 1991-1996 Silicon Graphics, Inc. # HylaFAX is a trademark of Silicon Graphics # # Permission to use, copy, modify, distribute, and sell this software and # its documentation for any purpose is hereby granted without fee, provided # that (i) the above copyright notices and this permission notice appear in # all copies of the software and related documentation, and (ii) the names of # Sam Leffler and Silicon Graphics may not be used in any advertising or # publicity relating to the software without the specific, prior written # permission of Sam Leffler and Silicon Graphics. # # THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, # EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY # WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. # # IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR # ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, # OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, # WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF # LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # OF THIS SOFTWARE. # # security NOCLOBBER_ON="set -o noclobber" NOCLOBBER_OFF="set +o noclobber" # # Print Statistics about Received Facsimile. # SPOOL=/var/spool/hylafax test -f $SPOOL/etc/setup.cache || { cat</dev/null` if test X$TMPDIR = X; then TMPDIR=/tmp/.recvstats$$ fi /bin/rm -fr $TMPDIR (umask 077 ; mkdir $TMPDIR) || exit 1 tmpAwk=$TMPDIR/xferfax$$ trap "/bin/rm -f $tmpAwk; /bin/rm -fr $TMPDIR; exit 1" 1 2 15 ($CAT<<'EOF' # # Setup date conversion data structures. # function setupDateTimeStuff() { daysInMonth[ 0] = 31; daysInMonth[ 1] = 28; daysInMonth[ 2] = 31; daysInMonth[ 3] = 30; daysInMonth[ 4] = 31; daysInMonth[ 5] = 30; daysInMonth[ 6] = 31; daysInMonth[ 7] = 31; daysInMonth[ 8] = 30; daysInMonth[ 9] = 31; daysInMonth[10] = 30; daysInMonth[11] = 31; FULLDAY = 24 * 60 * 60; } # # Convert hh:mm:ss to seconds. # function cvtTime(s) { t = i = 0; for (n = split(s, a, ":"); i++ < n; ) t = t*60 + a[i]; return t; } # # Convert MM/DD/YY hh:mm to seconds. # NB: this does not deal with leap years. # function cvtDateTime(s) { yday = substr(s,7,2); if (yday < 70) yday += 30; else yday -= 70; yday = yday*365 + substr(s,4,2) - 1; mon = substr(s,1,2) - 1; for (i = 0; i < mon; i++) yday += daysInMonth[i]; return yday*FULLDAY + cvtTime(substr(s,10) ":00"); } function setupDigits() { digits[0] = "0"; digits[1] = "1"; digits[2] = "2"; digits[3] = "3"; digits[4] = "4"; digits[5] = "5"; digits[6] = "6"; digits[7] = "7"; digits[8] = "8"; digits[9] = "9"; } # # Format seconds as hh:mm:ss. # function fmtTime(t) { v = int(t/3600); result = ""; if (v > 0) { if (v >= 10) result = digits[int(v/10)]; result = result digits[int(v%10)] ":"; t -= v*3600; } v = int(t/60); if (v >= 10 || result != "") result = result digits[int(v/10)]; result = result digits[int(v%10)]; t -= v*60; return (result ":" digits[int(t/10)] digits[int(t%10)]); } # # Setup map for histogram calculations # and indexed table for decoding params. # function setupMaps(s, map, names) { n = split(s, a, ":"); for (i = 1; i <= n; i++) { map[a[i]] = i; names[i-1] = a[i]; } } # # Add pages to a histogram. # function addToMap(key, ix, pages, map) { if (key == "") { for (i in map) key = key ":"; } n = split(key, a, ":"); a[map[ix]] += pages; t = a[1]; for (i = 2; i <= n; i++) t = t ":" a[i]; return t; } # # Return the name of the item with the # largest number of accumulated pages. # function bestInMap(totals, map) { n = split(totals, a, ":"); imax = 1; max = -1; for (j = 1; j <= n; j++) if (a[j] > max) { max = a[j]; imax = j; } split(map, a, ":"); return a[imax]; } # # Sort array a[l..r] # function qsort(a, l, r) { i = l; k = r+1; item = a[l]; for (;;) { while (i < r) { i++; if (a[i] >= item) break; } while (k > l) { k--; if (a[k] <= item) break; } if (i >= k) break; t = a[i]; a[i] = a[k]; a[k] = t; } t = a[l]; a[l] = a[k]; a[k] = t; if (k != 0 && l < k-1) qsort(a, l, k-1); if (k+1 < r) qsort(a, k+1, r); } function getBR(params) { if ((int(int(params) / 2097152) % 2) == 1) { return brNames[int(int(params) / 8) % 16]; } else { return brNames[int(int(params) / 2) % 8]; } } function getDF(params) { if ((int(int(params) / 2097152) % 2) == 1) { return dfNames[int(int(params) / 16384) % 4]; } else { return dfNames[int(int(params) / 512) % 4]; } } function hex(n) { # GNU Awk 3.1.3 has a type conversion error from hex strings, # so we have to do it the hard way val = 0; for (position = 1; position <= length(n); position++) { val = val * 16; char = tolower(substr(n, position, 1)); if (char == "a") val = val + 10; else if (char == "b") val = val + 11; else if (char == "c") val = val + 12; else if (char == "d") val = val + 13; else if (char == "e") val = val + 14; else if (char == "f") val = val + 15; else val = val + int(char); } return val; } function isBitSet(bit, dcs) { byte = int((bit - 1) / 8); pos = 7 - ((bit - 1) % 8); dcsbyte = hex(substr(dcs, (byte*3+1), 2)); return int(int(dcsbyte / (2 ^ pos)) % 2); } function getDFfromDCS(dcs) { if (substr(dcs, 1, 1) == "\"") dcs = substr(dcs, 2); if (substr(dcs, length(dcs), 1) == "\"") dcs = substr(dcs, 1, length(dcs)-1); if (isBitSet(68, dcs)) { if (isBitSet(69, dcs)) return dfNames[6]; return dfNames[5]; } if (isBitSet(78, dcs) || isBitSet(79, dcs)) return dfNames[4]; if (isBitSet(31, dcs)) return dfNames[3]; if (isBitSet(26, dcs)) return dfNames[2]; if (isBitSet(16, dcs)) return dfNames[1]; return dfNames[0]; } # # Accumulate a statistics record. # function acct(key, pages, time, br, df, status, cidname, cidnumber) { if (cvtDateTime($1) < KEEPSINCE || cvtDateTime($1) > KEEPEND) return; gsub("\"", "", key); gsub("^ +", "", key); gsub(" +$", "", key); recvpages[key] += pages; if (pages == 0 && time > 60) time = 0; recvtime[key] += cvtTime(time); gsub("\"", "", status); if (status != "") recverrs[key]++; gsub("\"", "", br); recvrate[key] = addToMap(recvrate[key], br, pages, rateMap); gsub("\"", "", df); recvdata[key] = addToMap(recvdata[key], df, pages, dataMap); gsub("\"", "", cidname); gsub("\"", "", cidnumber); lastcidname[key] = cidname; lastcidnumber[key] = cidnumber; } # # Print a rule between the stats and the totals line. # function printRule(n, s) { r = ""; while (n-- >= 0) r = r s; printf "%s\n", r; } BEGIN { FS="\t"; rates = "2400:4800:7200:9600:12000:14400:16800:19200:21600:24000:26400:28800:31200:33600"; setupMaps(rates, rateMap, brNames); datas = "1-D MH:2-D MR:2-D Uncompressed Mode:2-D MMR:JBIG:JPEG Greyscale:JPEG Full-color"; setupMaps(datas, dataMap, dfNames); setupDateTimeStuff(); if (SINCEDT == "") KEEPSINCE = cvtDateTime(TODAY) - AGE*FULLDAY; else KEEPSINCE = cvtDateTime(SINCEDT); if (ENDDT == "") KEEPEND = cvtDateTime(TODAY); else KEEPEND = cvtDateTime(ENDDT); } END { OFS="\t"; setupDigits(); maxlen = 15; nsorted = 0; for (i in recvpages) { l = length(i); if (l > maxlen) maxlen = l; sorted[nsorted++] = i; } qsort(sorted, 0, nsorted-1); fmt = "%-" maxlen "." maxlen "s" " %-" maxlen "." maxlen "s" " %-" maxlen "." maxlen "s"; # e.g. %-24.24s printf fmt " %5s %8s %6s %4s %7s %7s\n", "Sender", "CIDName", "CIDNumber", "Pages", "Time", "Pg/min", "Errs", "TypRate", "TypData"; tpages = 0; ttime = 0; terrs = 0; for (k = 0; k < nsorted; k++) { i = sorted[k]; t = recvtime[i]/60; if (t == 0) t = 1; n = recvpages[i]; if (n == 0) n = 1; brate = best printf fmt " %5d %8s %6.1f %4d %7d %7s\n", i, lastcidname[i], lastcidnumber[i], recvpages[i], fmtTime(recvtime[i]), recvpages[i] / t, recverrs[i], bestInMap(recvrate[i], rates), bestInMap(recvdata[i], datas); tpages += recvpages[i]; ttime += recvtime[i]; terrs += recverrs[i]; } printRule(maxlen+1+maxlen+1+maxlen+1+5+1+8+6+1+4+1+7+1+7, "-"); t = ttime/60; if (t == 0) t = 1; printf fmt " %5d %8s %6.1f %4d\n", "Total", "", "", tpages, fmtTime(ttime), tpages/t, terrs; } EOF echo "$AWKRULES" )>$tmpAwk $AWK -f $tmpAwk -v TODAY="$TODAY" -v AGE="$AGE" -v SINCEDT="$SINCEDT" -v ENDDT="$ENDDT" $FILES # cleanup /bin/rm -f $tmpAwk; /bin/rm -fr $TMPDIR exit 0