faxcron.sh.in
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:12k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. #! @SCRIPT_SH@
  2. # $Id: faxcron.sh.in,v 1.4 2008/10/13 05:09:02 faxguy Exp $
  3. #
  4. # HylaFAX Facsimile Software
  5. #
  6. # Copyright (c) 1993-1996 Sam Leffler
  7. # Copyright (c) 1993-1996 Silicon Graphics, Inc.
  8. # HylaFAX is a trademark of Silicon Graphics
  9. # Permission to use, copy, modify, distribute, and sell this software and 
  10. # its documentation for any purpose is hereby granted without fee, provided
  11. # that (i) the above copyright notices and this permission notice appear in
  12. # all copies of the software and related documentation, and (ii) the names of
  13. # Sam Leffler and Silicon Graphics may not be used in any advertising or
  14. # publicity relating to the software without the specific, prior written
  15. # permission of Sam Leffler and Silicon Graphics.
  16. # THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  17. # EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  18. # WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  19. # IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20. # ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21. # OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22. # WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23. # LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24. # OF THIS SOFTWARE.
  25. #
  26. #
  27. # Script to run periodically from cron:
  28. #
  29. # 0. Print transmit and receive statistics.
  30. # 1. Purge info directory of old remote machine capabilities.
  31. # 2. Purge old session logs from the log directory.
  32. # 3. Purge old files in the received facsimile queue.
  33. # 4. Notify about sites that currently have jobs rejected.
  34. #
  35. AGEINFO=30 # purge remote info after 30 days inactivity
  36. AGELOG=30 # keep log info for last 30 days
  37. AGERCV=7 # purge received facsimile after 7 days
  38. AGETMP=1 # purge orphaned temp files after 1 day
  39. FAXUSER=@FAXUID@ # owner of log files
  40. SPOOL=@SPOOL@ # HylaFAX spool directory
  41. LOGMODE=0644 # mode for log files
  42. XFERLOG=etc/xferfaxlog # HylaFAX xferfaxlog file location
  43. LAST=etc/lastrun # file where time+date of last run recorded
  44. TEE=tee
  45. UPDATE="date +'%D %H:%M' >$LAST"
  46. while [ x"$1" != x"" ] ; do
  47.     case $1 in
  48.     -n)     RM=":" TEE=":" CP=":" MV=":" CHOWN=":" CHMOD=":" UPDATE=":";;
  49.     -l)     shift; LASTRUN="$1";;
  50.     -q)     shift; SPOOL="$1";;
  51.     -info)  shift; AGEINFO="$1";;
  52.     -log)   shift; AGELOG="$1";;
  53.     -rcv)   shift; AGERCV="$1";;
  54.     -tmp)   shift; AGETMP="$1";;
  55.     -mode)  shift; LOGMODE="$1";;
  56.     -*)     echo "Usage: $0 [-n] [-l lastrun] [-q spool] [-info days] [-log days] [-rcv days] [-tmp days] [-mode logmode]"; hfExit 1;;
  57.     esac
  58.     shift
  59. done
  60. cd $SPOOL # NB: everything below assumes this
  61. . bin/common-functions
  62. test -f etc/setup.cache || {
  63.     SPOOL=`pwd`
  64.     cat<<EOF
  65. FATAL ERROR: $SPOOL/etc/setup.cache is missing!
  66. The file $SPOOL/etc/setup.cache is not present.  This
  67. probably means the machine has not been setup using the faxsetup(@MANNUM1_8@)
  68. command.  Read the documentation on setting up HylaFAX before you
  69. startup a server system.
  70. EOF
  71.     hfExit 1
  72. }
  73. . etc/setup.cache
  74. RM="$RM -f"
  75. # security
  76. SetupPrivateTmp
  77. JUNK=$TMPDIR/faxjunk$$         # temp file used multiple times
  78. AWKTMP=$TMPDIR/faxawk$$                # temp file for awk program
  79. test -z "$LASTRUN" && LASTRUN=`$CAT $LAST 2>/dev/null`
  80. echo "Facsimile transmitted since $LASTRUN:"
  81. echo ""
  82. $SBIN/xferfaxstats -since "$LASTRUN" 
  83. echo ""
  84. echo "Facsimile transmitted in the last seven days:"
  85. echo ""
  86. $SBIN/xferfaxstats -age 7
  87. echo ""
  88. echo "Facsimile received since $LASTRUN:"
  89. echo ""
  90. $SBIN/recvstats -since "$LASTRUN" 
  91. echo ""
  92. echo "Facsimile received in the last seven days:"
  93. echo ""
  94. $SBIN/recvstats -age 7
  95. echo ""
  96. echo "Report failed calls and associated session logs:"
  97. $CAT>$AWKTMP<<'EOF'
  98. #
  99. # Sort array a[l..r]
  100. #
  101. function qsort(a, l, r) {
  102.     i = l;
  103.     k = r+1;
  104.     item = a[l];
  105.     for (;;) {
  106. while (i < r) {
  107.             i++;
  108.     if (a[i] >= item)
  109. break;
  110.         }
  111. while (k > l) {
  112.             k--;
  113.     if (a[k] <= item)
  114. break;
  115.         }
  116.         if (i >= k)
  117.     break;
  118. t = a[i]; a[i] = a[k]; a[k] = t;
  119.     }
  120.     t = a[l]; a[l] = a[k]; a[k] = t;
  121.     if (k != 0 && l < k-1)
  122. qsort(a, l, k-1);
  123.     if (k+1 < r)
  124. qsort(a, k+1, r);
  125. }
  126. function cleanup(s)
  127. {
  128.     gsub(""", "", s);
  129.     gsub("^ +", "", s);
  130.     gsub(" +$", "", s);
  131.     return s;
  132. }
  133. function setupToLower()
  134. {
  135.     upperRE = "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]";
  136.     upper["A"] = "a"; upper["B"] = "b"; upper["C"] = "c";
  137.     upper["D"] = "d"; upper["E"] = "e"; upper["F"] = "f";
  138.     upper["G"] = "g"; upper["H"] = "h"; upper["I"] = "i";
  139.     upper["J"] = "j"; upper["K"] = "k"; upper["L"] = "l";
  140.     upper["M"] = "m"; upper["N"] = "n"; upper["O"] = "o";
  141.     upper["P"] = "p"; upper["Q"] = "q"; upper["R"] = "r";
  142.     upper["S"] = "s"; upper["T"] = "t"; upper["U"] = "u";
  143.     upper["V"] = "v"; upper["W"] = "w"; upper["X"] = "x";
  144.     upper["Y"] = "y"; upper["Z"] = "z";
  145. }
  146. function toLower(s)
  147. {
  148.     if (match(s, upperRE) != 0) {
  149. do {
  150.     c = substr(s, RSTART, 1);
  151.     gsub(c, upper[c], s);
  152. } while (match(s, upperRE));
  153.     }
  154.     return s;
  155. }
  156. #
  157. # Accumulate a statistics record.
  158. #
  159. function acct(dest, status, datetime, commid)
  160. {
  161.     split(datetime, a, " ");
  162.     split(a[1], b, "/");
  163.     t = b[3] b[1] b[2] a[2];
  164.     if (t < LASTt)
  165. return;
  166.     status = cleanup(status);
  167.     if (length(status) > 11) {
  168. msg = toLower(substr(status, 1, 11));
  169. if (callFailed[msg])
  170.     return;
  171.     }
  172.     if (status != "") {
  173. dest = cleanup(dest);
  174. datetime = cleanup(datetime);
  175. for (i = 0; i < nerrmsg; i++)
  176.     if (errmsg[i] == status)
  177. break;
  178. if (i == nerrmsg)
  179.     errmsg[nerrmsg++] = status;
  180. if (errinfo[dest] == "")
  181.     errinfo[dest] = datetime "@" i "/" commid;
  182. else
  183.     errinfo[dest] = errinfo[dest] "|" datetime "@" i "/" commid;
  184.     }
  185. }
  186. function printOldTranscript(canon, datetime)
  187. {
  188.     gsub("[^0-9]", "", canon);
  189.     split(datetime, parts, " ");
  190.     split(parts[1], p, "/");
  191.     cmd = sprintf(TRANSCRIPT, canon, months[p[1]], p[2], parts[2]);
  192.     system(cmd);
  193. }
  194. function printTranscript(commid)
  195. {
  196.     printf "n    ---- Transcript of session follows ----nn"
  197.     comFile = "log/c" commid;
  198.     if ((getline <comFile) > 0) {
  199. do {
  200.     if (index($0, "-- data") == 0)
  201. print $0
  202. } while ((getline <comFile) > 0);
  203. close(comFile);
  204.     } else
  205. print "No transcript available.";
  206. }
  207. BEGIN { FS="t";
  208.   callFailed["Busy signal"] = 1;
  209.   callFailed["Unknown pro"] = 1;
  210.   callFailed["No carrier "] = 1;
  211.   callFailed["No local di"] = 1;
  212.   callFailed["No answer f"] = 1;
  213.   callFailed["Job aborted"] = 1;
  214.   callFailed["Invalid dia"] = 1;
  215.   callFailed["Can not loc"] = 1;
  216.   months["01"] = "Jan"; months["02"] = "Feb";
  217.   months["03"] = "Mar"; months["04"] = "Apr";
  218.   months["05"] = "May"; months["06"] = "Jun";
  219.   months["07"] = "Jul"; months["08"] = "Aug";
  220.   months["09"] = "Sep"; months["10"] = "Oct";
  221.   months["11"] = "Nov"; months["12"] = "Dec";
  222.   split(LASTRUN, a, " ");
  223.   split(a[1], b, "/");
  224.   LASTt = b[3] b[1] b[2] a[2];
  225.   setupToLower();
  226. }
  227. $2 == "SEND" && NF == 9  { acct($4,  $9, $1, ""); }
  228. $2 == "SEND" && NF == 11 { acct($5, $11, $1, ""); }
  229. $2 == "SEND" && NF == 12 { acct($6, $12, $1, ""); }
  230. $2 == "SEND" && NF == 13 { acct($7, $13, $1, $3); }
  231. $2 == "SEND" && NF == 14 { acct($7, $14, $1, $3); }
  232. END { nsorted = 0;
  233.   for (key in errinfo)
  234.       sorted[nsorted++] = key;
  235.   qsort(sorted, 0, nsorted-1);
  236.   for (k = 0; k < nsorted; k++) {
  237.       key = sorted[k];
  238.       n = split(errinfo[key], a, "|");
  239.       for (i = 1; i <= n; i++) {
  240.   if (split(a[i], b, "@") != 2)
  241.       continue;
  242.   if (split(b[2], d, "/") != 2)
  243.       continue;
  244.   printf "n"
  245.   printf "To: %-16.16s  Date: %sn", key, b[1]
  246.   printf "Error: %snn", errmsg[d[1]]
  247.   if (d[2] == "")
  248.       printOldTranscript(key, b[1]);
  249.   else
  250.       printTranscript(d[2]);
  251.       }
  252.   }
  253. }
  254. EOF
  255. $AWK -f $AWKTMP -v LASTRUN="$LASTRUN" TRANSCRIPT="
  256.     LOGFILE=log/%s;
  257.     TMP=$TMPDIR/faxlog$$;
  258.     if [ -f $LOGFILE ]; then
  259. $SED -n -e '/%s %s %s.*SESSION BEGIN/,/SESSION END/p' $LOGFILE |
  260. $SED -e '/start.*timer/d'
  261.      -e '/stop.*timer/d'
  262.      -e '/-- data/d'
  263.      -e 's/^/    /' >$TMP;
  264.     fi;
  265.     if [ -s $TMP ]; then
  266. $CAT $TMP;
  267.     else
  268. echo '    No transcript available.';
  269.     fi;
  270.     rm -f $TMP
  271.     " $XFERLOG
  272. echo ""
  273. #
  274. # Collect phone numbers that haven't been called
  275. # in the last $AGEINFO days.  We use this to clean
  276. # up the info files.
  277. #
  278. find info -type f -ctime +$AGEINFO -print >$JUNK
  279. if [ -s $JUNK ]; then
  280. echo "Purge remote device capabilities older than $AGEINFO days:"
  281. INFOTMP=info/tmp$$
  282. for i in `$CAT $JUNK`; do
  283.     if $GREP '^&' $i >/dev/null 2>&1; then
  284. echo "    $i (saving locked down values)"
  285. $SED '/^[^&]/d' $i > $INFOTMP
  286. $MV $INFOTMP $i; $CHOWN ${FAXUSER} $i; $CHMOD ${LOGMODE} $i
  287.     elif [ -f $i ]; then
  288. echo "    $i"
  289. $RM $i
  290.     fi
  291. done
  292. $RM $INFOTMP # for -n option
  293. else 
  294.     echo "Nothing to purge in info directory."
  295. fi
  296. echo ""
  297. find log -type f -mtime +$AGELOG ! -name seqf -print >$JUNK
  298. if [ -s $JUNK ]; then
  299.     echo "Purge session logs older than $AGELOG days:"
  300.     for i in `$CAT $JUNK`; do
  301. echo "    Remove $i"
  302. $RM $i
  303.     done
  304.     echo ""
  305. fi
  306. echo "Truncate merged session logs older than $AGELOG days:"
  307. $CAT>$AWKTMP<<'EOF'
  308. #
  309. # Setup date conversion data structures.
  310. #
  311. function setupDateTimeStuff()
  312. {
  313.     Months["Jan"] =  0; Months["Feb"] =  1; Months["Mar"] =  2;
  314.     Months["Apr"] =  3; Months["May"] =  4; Months["Jun"] =  5;
  315.     Months["Jul"] =  6; Months["Aug"] =  7; Months["Sep"] =  8;
  316.     Months["Oct"] =  9; Months["Nov"] = 10; Months["Dec"] = 11;
  317.     daysInMonth[ 0] = 31; daysInMonth[ 1] = 28; daysInMonth[ 2] = 31;
  318.     daysInMonth[ 3] = 30; daysInMonth[ 4] = 31; daysInMonth[ 5] = 30;
  319.     daysInMonth[ 6] = 31; daysInMonth[ 7] = 31; daysInMonth[ 8] = 30;
  320.     daysInMonth[ 9] = 31; daysInMonth[10] = 30; daysInMonth[11] = 31;
  321.     FULLDAY = 24 * 60 * 60;
  322. }
  323. #
  324. # Convert MMM DD hh:mm:ss.ms to seconds.
  325. # NB: this does not deal with leap years.
  326. #
  327. function cvtTime(s)
  328. {
  329.     mon = Months[substr(s, 1, 3)];
  330.     yday = substr(s, 5, 2) - 1;
  331.     for (i = 0; i < mon; i++)
  332. yday += daysInMonth[i];
  333.     s = substr(s, 7);
  334.     t = i = 0;
  335.     for (n = split(s, a, ":"); i++ < n; )
  336. t = t*60 + a[i];
  337.     return yday*FULLDAY + t;
  338. }
  339. BEGIN { setupDateTimeStuff();
  340.   KEEP = cvtTime(TODAY) - AGE*FULLDAY;
  341.   lastRecord = "$"
  342. }
  343. { if (cvtTime($1 ":" $2 ":" $3) >= KEEP) {
  344.       lastRecord = NR; exit
  345.   }
  346. }
  347. END { print lastRecord }
  348. EOF
  349. TODAY="`date +'%h %d %T'`"
  350. for i in log/[0-9]*; do
  351.     if [ -f $i ]; then
  352. START=`$AWK -F: -f $AWKTMP -v TODAY="$TODAY" -v AGE=$AGELOG $i` 2>/dev/null
  353. if [ "$START" != 1 ]; then
  354.     $SED 1,${START}d $i >$JUNK
  355.     if [ -s $JUNK ]; then
  356. $MV $JUNK $i; $CHOWN ${FAXUSER} $i; $CHMOD ${LOGMODE} $i
  357. ls -ls $i
  358.     else
  359. echo "    Remove empty $i"
  360. $RM $i
  361.     fi
  362. fi
  363.     fi
  364. done
  365. echo ""
  366. #
  367. # Purge old stuff from the receive queue.
  368. #
  369. find recvq -type f -mtime +$AGERCV ! -name seqf -print >$JUNK
  370. if [ -s $JUNK ]; then
  371.     echo "Purge received facsimile older than $AGERCV days:"
  372.     (for i in `$CAT $JUNK`; do
  373. $SBIN/faxinfo $i
  374. $RM $i >/dev/null 2>&1
  375.     done) | $AWK -F: '
  376. /recvq.*/ { file=$1; }
  377. /Sender/ { sender = $2; }
  378. /Pages/ { pages = $2; }
  379. /Quality/ { quality = $2; }
  380. /Received/ { date = $2;
  381.   for (i = 3; i <= NF; i++)
  382.       date = date ":" $i;
  383.   printf "    %-18.18s %21.21s %2d %8s%sn", 
  384. file, sender, pages, quality, date;
  385. }
  386. '
  387. else
  388.     echo "Nothing to purge in receive queue."
  389. fi
  390. echo ""
  391. #
  392. # Purge old stuff from the temp directory.
  393. #
  394. find tmp -type f -mtime +$AGETMP -print >$JUNK
  395. if [ -s $JUNK ]; then
  396.     echo "Purge tmp files older than $AGETMP days:"
  397.     for i in `$CAT $JUNK`; do
  398.       if [ -f $i ]; then
  399. echo "    Remove $i"
  400. $RM $i
  401.       fi
  402.     done
  403. else
  404.     echo "Nothing to purge in the tmp directory."
  405. fi
  406. echo ""
  407. #
  408. # Note destinations whose jobs are currently being rejected.
  409. #
  410. find info cinfo -type f -newer $LAST -print 2>/dev/null >$JUNK
  411. if [ -s $JUNK ]; then
  412. echo "Destinations being rejected (added since $LASTRUN):"
  413. (for i in `$CAT $JUNK`; do $GREP "^rejectNotice:" $i; done) | $AWK -F: '
  414. { reason = $3;
  415.   for (i = 4; i <= NF; i++)
  416. reason = reason ":" $i;
  417.   sub("^[ ]*", "", reason);
  418.   if (reason != "") {
  419.       sub(".*/", "", $1);
  420.       printf "Rejecting jobs to +%s because "%s".n", 
  421.     $1, reason;
  422.   }
  423. }
  424. '
  425. fi
  426. $RM $LAST; eval $UPDATE
  427. # cleanup
  428. hfExit 0